/*
 * Description: Driver of Digital Outputs
 * **********************************************************
 */

/*
 * **********************************************************
 * PreDefines
 * **********************************************************
 */


//#define	__PCF8574__

/*
 * **********************************************************
 * Include Files
 * **********************************************************
 */
#include <string.h>
#include "stdio.h"
#include <math.h>
#include <string.h>
#include "main.h"
#include "uart.h"
#include "Timer.h"
#include "AI.h"
#include "Pid.h"
#include "Register.h"
#include "ModbusRegister.h"
#include "Settings.h"
#include "EEPROM.h" 
#include "DigitalIn.h"
#include "DigitalOut.h"
#include "IDriver.h"
#include "ModbusRegister.h"
#include "spi.h"
#include "Control.h"
#include "Timer.h"
#include "ModbusRtu.h"
#include "fan_ctrl.h"
#include "sec_delay.h"
#include "EquivalentTemp.h"
#include "hal_exp_valve.h"

extern VALVE ElectricValve;

uint8_t init_delay = 10;
uint8_t factory_test = 0;
uint8_t  factory_test_stage = 0;
uint8_t factory_test_error = 0;
uint8_t  factory_test_count =0;
uint8_t factory_timeout = 0;
uint8_t sec_flag = 0;
static uint8_t FanConfirmTimes;
static uint8_t fan1_err_times;
static uint8_t fan2_err_times;
static uint8_t WinterFlag;
static uint8_t CMPR_Start_Flag;
static uint16_t factory_test_delay;
static uint8_t cmpr_speed;
static uint16_t fan_speed[2];
static uint8_t Last_cmpr_speed;
static uint16_t Last_fan_speed[2];
int16_t InputReg[IREG_MAX];

#define ERROR_STATE_SIZE  100

DEVICE_STATE CMPR_Cmd;
DEVICE_STATE CMPR_State;
uint8_t start_protection_state = 0;  
EEV_SET EEValveState; 

ERROR_BIT Device_Error;

uint8_t errorState[ERROR_STATE_SIZE];
uint8_t errorStateIndex = 0;
uint8_t FanStart = 0;
uint8_t td_rise_flag = 0;
/*
 * **********************************************************
 * Private Variables
 * **********************************************************
 */
 
uint16_t protect_start_delay = 0;    //Frequently Start Protection
uint16_t protect_stop_delay = 0;    //Frequently Start Protection
uint8_t lastError = 0;

//static s16 temptemp=900;

static u32 Update,TimersSecondUpdate;//,TimersUpdate;//TimersUpdate
//static u32 Update1;
//static u8 Stri2Mode_flag;
u16 wLastTime, wDefrostStartTime, wDefrostStopTime;
PACK ASDPack;



//PRINT_IERM *PrintStrUnit;
uint16_t fail_to_restart = 0;

//LOOP	   PIDLoop[3];
//uint16_t FanRunHr[2];
uint16_t cmpr_tick = 0;
uint32_t fan_tick = 0;

static uint16_t cmprOnSeconds;
static s16 up_limit_frequence;
static uint8_t levela_error[2];
static uint8_t levelb_error[2];
static uint8_t levelc_error[20];
static uint8_t leveld_error[4];
static uint8_t levele_error[2];
CMPR_REQ cmpr_req;
CMPR_ACK cmpr_ack;
CMPR_FORCE_FORBIT cmpr_force_forbit;

PID_PARAMETERS PidPara[3];
PID_SET	   CmprPID;
PID_SET	   FanPID;


OIL_COLLECT oilCol;
uint8_t control_State = 0; //

DELAY delay_err_reset;
DELAY delay_heater;
DELAY delay_ps_flt;      //5s
DELAY delay_pd_flt;      //5s
DELAY delay_td_flt;
DELAY delay_ts_flt;
DELAY delay_os_flt;
DELAY delay_ps_gt_psu;  //Ps > PsU, 3s
DELAY delay_ps_lt_psu;  //Ps < PsD, 180s
DELAY delay_ps_lo;      //Ps <= A
DELAY delay_pd_hi;      //Pd > 41bar, 5s
DELAY delay_td_hi;      //Td > 120, 60s
DELAY delay_tssh_lo;    //TsSH < 5, 180s
DELAY delay_cmpr_init;    //Init Frq Holding
DELAY delay_cmpr_pd_ps_lo;  //Pd/Ps Lo
DELAY delay_cmpr_hold;

uint16_t delay_td_lo = 0;      //Td < 10, 30s
uint16_t delay_pd_lo = 0;      //Ps <= A
uint16_t delay_ps_hi = 0;      //Ps <= A

uint8_t limit_max = 90;
uint8_t limit_tick = 0;


DELAY delay_freq_lo_pd_hi;
DELAY delay_ipm_temp_hi;

DELAY delay_eev_init;
DELAY delay_twinkle;
DELAY delay_keypad_set;

DELAY delay_fan1_start;
DELAY delay_fan2_start;
DELAY delay_fan1_trm;
DELAY delay_fan2_trm;
DELAY delay_fan_stop;
DELAY delay_fan1_fault;
DELAY delay_fan2_fault;

DELAY delay_fan1_recover;
DELAY delay_fan2_recover;

DELAY transducer_8p_wait;    // 8P trip delay
uint8_t transducer_8p_fail;  // 8P fail count
DELAY transducer_8p_quit;    // 8P trip delay


DELAY delay_cmpr_run_on_fail;
DELAY delay_cmpr_stop_on_fail;

DELAY delay_cmpr_run_on_fail_ot;
DELAY delay_cmpr_stop_on_fail_ot;

DELAY delay_oil_collect_30;
DELAY delay_oil_collect_3;

DELAY delay_jet_liq_on;
DELAY delay_jet_liq_off;

DELAY td_hi_err_reset;
DELAY td_hi_times_reset;
uint8_t Error_Td_Hi_Times = 0;

DELAY delay_cmpr_err_times_reset;
uint8_t Error_CMPR_Err_Times = 0;
uint8_t cmpr_error, last_cmpr_error = 0;
uint8_t oil_collect_state = 0;

uint8_t delay_sec_flag = 0;
uint8_t start_delay = 60;
//MTIMER tm_tdsh_cycle_sec;
//MTIMER tm_force_inc_dec_sec;
uint16_t wait_start_delay = 0;
uint16_t fan_wait_start_delay = 0;
uint16_t winter_quit_delay = 0;
uint16_t wait_stop_delay = 0;
uint16_t freq_low_stop_delay = 0;
uint16_t ps_low_stop_delay = 0;

float cmpr_pd_ps_rate;



const  u8  PRODUCT_MODE[10] = "JD-FRC-001";


uint8_t HAL_DI_GetSwitchValue(void)
{
	return (uint8_t)((~GPIOE->IDR) & 0x00FF);
}



u16 GetPackOutputs(void)
{
	return ASDPack.DOOutput;

}


u16 GetAlarmWaitTimer(void)
{
	return ASDPack.AlarmWaitTimer;

}


static void ResetCapacityTimer(u8 Timer,u8 i)
{
	u16 Delay;
	
	switch(Timer)
	{        
		case TM_TDSH_CYCLE_SEC: 
			Delay = 10;//10��
			break;   

		case TM_FORCE_INC_DEC_SEC: 
			Delay = 1;//  1��
			break;
				
		default:
			break;
	}
	switch(Timer)
	{       
		case TM_TDSH_CYCLE_SEC:
			ASDPack.tm_tdsh_cycle_sec = Delay;
			break;

		case TM_FORCE_INC_DEC_SEC:	
			ASDPack.tm_force_inc_dec_sec = Delay;
			break;
		
		default:
			break;
			    
	}
}


void update_cmpr_ack_time(int8_t t) 
{
  if (t) 
  {
    if(++cmpr_ack.cmpr_ack_ot_times>= 30)
    {
      cmpr_ack.cmpr_ack_ot_times= 30;
    }
  }
  else
  {
    cmpr_ack.cmpr_ack_ot_times= 0;
  }
}



void Update_Comp_Ack(void)
{
	update_cmpr_ack_time(0);

}	


// Return 1: In Protection, Can not Start
// Return 0: Ready to Start
uint8_t Device_FrequentlyStartupProtect(void)
{
  static uint8_t last_di_cmpr_run_st= 0;
  uint16_t start_interval;
  
  start_interval= GetJDASDParamValue(HREG_START_INTERVAL);

  if(protect_start_delay)
  {
    protect_start_delay-= delay_sec_flag;
  }
  
  if(protect_stop_delay)
  {
    protect_stop_delay-= delay_sec_flag;
  }
  
  delay_sec_flag = 0;
  
  if(last_di_cmpr_run_st!= InputReg[REG_CMPR_START])
  {
    last_di_cmpr_run_st= InputReg[REG_CMPR_START];
    
    if(InputReg[REG_CMPR_START])
    {
      protect_start_delay= start_interval;
      if ((HAL_DI_GetSwitchValue() & 0xC0) == 0xC0)
			//if ((	IGet_DI_States(0) & 0xC0) == 0xC0) //8P
      { // 8P
	      Delay_Start(&transducer_8p_wait);
	      Delay_Start(&transducer_8p_quit);
      }
    }
    else
    {
      protect_stop_delay= GetJDASDParamValue(HREG_NEXT_START_DELAY);
    }
  }
  
  if((protect_start_delay || protect_stop_delay) && InputReg[REG_CMPR_START] == 0)
  {
    return 1;
  }
  
  return 0;
}



void Device_Timer(void)
{
  static uint8_t sec_cnt= 0;
  
 // if(Timer_Expires(&tm_one_tenth_sec))
  {
    //Delay Timer
    Delay_Check(&delay_err_reset);
		
		Delay_Check(&delay_heater);
    
    Delay_Check(&delay_ps_gt_psu);
    
    Delay_Check(&delay_ps_lo);
    
    Delay_Check(&delay_td_hi);
    
    Delay_Check(&delay_pd_hi);
    
    Delay_Check(&delay_pd_flt);
    
    Delay_Check(&delay_ps_flt);
		
		Delay_Check(&delay_td_flt);
		
		Delay_Check(&delay_ts_flt);
		
		Delay_Check(&delay_ipm_temp_hi);
		
		Delay_Check(&delay_os_flt);
    
    Delay_Check(&delay_tssh_lo);
    
    Delay_Check(&delay_cmpr_init);
    
    Delay_Check(&delay_cmpr_pd_ps_lo);
		
		Delay_Check(&delay_cmpr_hold);
    
    Delay_Check(&delay_eev_init);
    
    Delay_Check(&delay_twinkle);
    
    Delay_Check(&delay_keypad_set);
    
    Delay_Check(&td_hi_err_reset);
    Delay_Check(&td_hi_times_reset);
    
    Delay_Check(&delay_freq_lo_pd_hi);

    Delay_Check(&delay_cmpr_err_times_reset);
    
    Delay_Check(&delay_oil_collect_30);
    Delay_Check(&delay_oil_collect_3);
		
		Delay_Check(&delay_jet_liq_on);
		Delay_Check(&delay_jet_liq_off);

    Delay_Check(&delay_fan_stop);
		Delay_Check(&delay_fan1_start);
		Delay_Check(&delay_fan1_trm);
		Delay_Check(&delay_fan1_fault);
		Delay_Check(&delay_fan1_recover);
		Delay_Check(&delay_fan2_start);
		Delay_Check(&delay_fan2_trm);
		Delay_Check(&delay_fan2_fault);
    Delay_Check(&delay_fan2_recover);
    Delay_Check(&delay_cmpr_run_on_fail);
    Delay_Check(&delay_cmpr_stop_on_fail);
		
		Delay_Check(&delay_cmpr_run_on_fail_ot);
    Delay_Check(&delay_cmpr_stop_on_fail_ot);

    Delay_Check(&transducer_8p_wait);
    Delay_Check(&transducer_8p_quit);

    // Second
    if(++sec_cnt >= 10)
    {
      sec_cnt= 0;

//      if(InputReg[REG_DO_FAN_SS_1])
//      {
//        FanRunHr[0]++;
//      }
//      
//      if(InputReg[REG_DO_FAN_SS_2])
//      {
//        FanRunHr[1]++;
//      }
      
      if(fail_to_restart)
      {
        fail_to_restart--;
      }
      
      start_protection_state= Device_FrequentlyStartupProtect();
    }
  }
}



static void DecrementMSTimers(void)
{
	
	//	Delay_Check(&delay_cmpr_init);
	Device_Timer();


}


static void DecrementTimers(void)
{   
	
	if(init_delay > 0)
	{
		init_delay--;

	}
	if(start_delay > 0)
	{
		start_delay--;

	}

	if( ASDPack.PowerOnWaitTimer)
	{
		ASDPack.PowerOnWaitTimer--;
		return;

	}

	if( ASDPack.tm_tdsh_cycle_sec)
	{
		ASDPack.tm_tdsh_cycle_sec--;

	}

	if(ASDPack.tm_force_inc_dec_sec)
	{
		ASDPack.tm_force_inc_dec_sec--;

	}
	delay_sec_flag = 1;
	sec_flag = 1;

	update_cmpr_ack_time(1);


	if(factory_test_delay > 0)
	{
		factory_test_delay--;

	}
	  
}


void SC_PackReset(void)
{
	ASDPack.Status = 0;	
	//Alarm_Reset();
//	ASDPack.DZtimes = 0;
}

void update_device_state() 
{
  cmpr_ack.fan_1_rpm = Get_feedBackSpeed(0); //1:5-6
  cmpr_ack.fan_2_rpm = Get_feedBackSpeed(1);
  InputReg[REG_FAN_SP_1] = cmpr_ack.fan_1_rpm;
  InputReg[REG_FAN_SP_2] = cmpr_ack.fan_2_rpm;
	
  cmpr_ack.cmpr_rps = Get_ModbusSlaveData(0); //0:4-5
  cmpr_ack.current =  Get_ModbusSlaveData(1);	//1:6-7
  cmpr_ack.voltage_ac = Get_ModbusSlaveData(2); //2:8-9
  cmpr_ack.voltage_dc = Get_ModbusSlaveData(3);  //3:10-11
  cmpr_ack.phase_curr = Get_ModbusSlaveData(4); ; //4:12-13
  cmpr_ack.temp_ipm = Get_ModbusSlaveData(5);  //5:14-15
  cmpr_ack.error_codeH = Get_ModbusSlaveData(6); //6:16-17
	cmpr_ack.error_codeL = Get_ModbusSlaveData(7); //7:18-19
	cmpr_ack.error_pfcH = Get_ModbusSlaveData(8);	//8:20-21
	cmpr_ack.error_pfcL = Get_ModbusSlaveData(9);	//9:22-23
  cmpr_ack.pfc_version = Get_ModbusSlaveData(10); //10:24-25
	
	//cmpr_ack.cur_freq = Get_ModbusSlaveData(11);
	//cmpr_ack.drv_version = Get_ModbusSlaveData(13);
	
  //cmpr_ack.pfc_state = pdu[23]; //10:23-24
	cmpr_ack.error_code = cmpr_ack.error_codeH;
	cmpr_ack.error_code <<= 16;
	cmpr_ack.error_code |= cmpr_ack.error_codeL;

	cmpr_ack.pfc_code = cmpr_ack.error_pfcH ;
	cmpr_ack.pfc_code  <<= 16;
	cmpr_ack.pfc_code |= cmpr_ack.error_pfcL;
	
	InputReg[REG_CMPR_FRQ]= cmpr_ack.cmpr_rps;
  InputReg[REG_TD_RPS]= cmpr_ack.cmpr_rps;
  InputReg[REG_CURRENT]= cmpr_ack.current;
  InputReg[REG_AC_CURRENT]= cmpr_ack.current;
  InputReg[REG_DC_CURRENT]= cmpr_ack.phase_curr;
  InputReg[REG_AC_VOLTAGE]= cmpr_ack.voltage_ac;
  InputReg[REG_TD_DC_VOLTAGE]= cmpr_ack.voltage_dc;
  InputReg[REG_TD_PHASE_CURRENT]= cmpr_ack.phase_curr;
  InputReg[REG_TD_IPM]= cmpr_ack.temp_ipm;
  InputReg[REG_ERROR_CODE_1]= cmpr_ack.error_codeH;
  InputReg[REG_ERROR_CODE_2]= cmpr_ack.error_codeL;
  InputReg[REG_PFC_CODE_1]= cmpr_ack.error_pfcH;
  InputReg[REG_PFC_CODE_2]= cmpr_ack.error_pfcL;
	InputReg[REG_DRV_VERSION] = cmpr_ack.pfc_version;
}


void Device_SetOutputValue(void)
{
	if(InputReg[REG_VALVE_1])
	{
		ISet_DO_Through(DO_VALVE_1);

	}
	else
	{
		ISet_DO_Break(DO_VALVE_1);

	}

	if(InputReg[REG_VALVE_2])
	{
		ISet_DO_Through(DO_VALVE_2);

	}
	else
	{
		ISet_DO_Break(DO_VALVE_2);

	}

	if(InputReg[REG_DO_CMPR_HTR])
	{
		ISet_DO_Through(DO_CMPR_HTR);

	}
	else
	{
		ISet_DO_Break(DO_CMPR_HTR);

	}

	InputReg[REG_REQUIRE_RPS]= cmpr_req.cmpr_rps;
}

void UpdateCompStatus()
{
  update_device_state();
	
}



void do_factory_test(int t)
{
  float v = 0;
  if (!sec_flag)
  {
    return;
  }
    
  if (factory_test_count < 3 && factory_test_stage < 15)
  {
    factory_test_count++;
    return;
  }
  else
  {
    factory_test_count = 0;
  }
  switch(factory_test_stage)
  {
    case 0: //
     // v = Temp_GetTempValue(TEMP_DISCHG, NTC_50K_B3970);
			v = IGet_AI_Scaled_Value(ADC_CHN_T1);
      if (v > -300 && v < 1500)
      {
        factory_test_stage = 1;
      }
      else
      {
        factory_test_stage = 255;
        factory_test_error = 1;
      }
      break;
    case 1: //
      //v = Temp_GetTempValue(TEMP_SUCTION, NTC_5K_A501440);
		  v = IGet_AI_Scaled_Value(ADC_CHN_T2);
      if (v > -300 && v < 1100)
      {
        factory_test_stage = 2;
      }
      else
      {
        factory_test_stage = 255;
        factory_test_error = 2;
      }
      break;
    case 2: 
     // v = Temp_GetTempValue(TEMP_OUTDOOR, NTC_5K_A501440);
		   v = IGet_AI_Scaled_Value(ADC_CHN_T3);
      if (v > -300 && v < 1100)
      {
        factory_test_stage = 3;
      }
      else
      {
        factory_test_stage = 255;
        factory_test_error = 3;
      }
      break;
    case 3:
      v = Press_GetGagePress(AI_HI_PRESS);
      if (v > 50 && v < 2500)
      {
        factory_test_stage = 4;
      }
      else
      {
        factory_test_stage = 255;
        factory_test_error = 4;
      }
      break;
    case 4:
      v = Press_GetGagePress(AI_LO_PRESS);
      if (v > 50 && v < 2500)
      {
        factory_test_stage = 5;
      }
      else
      {
        factory_test_stage = 255;
        factory_test_error = 5;
      }
      break;
    case 5: //
      if (IGet_DI_State(DI_CMPR_RUN) == 0)
      {
        factory_test_stage = 255;
        factory_test_error = 6;
      }
      else if (IGet_DI_State(DI_HI_PRESS) == 0)
      {
        factory_test_stage = 255;
        factory_test_error = 7;
      }
      else if (IGet_DI_State(DI_REMOTE_ON) == 0)
      {
        factory_test_stage = 255;
        factory_test_error = 8;
      }
      else
      {
        factory_test_stage = 6;
      }
      break;
    case 6: // DO1
			ISet_DO_Through(DO_CHN_1);
      //HAL_DO_SetChannelValue(DO_CHN_1, 1);
      factory_test_stage = 7;
      break;
    case 7: // DO2
      ISet_DO_Break(DO_CHN_1);
      ISet_DO_Through(DO_CHN_2);
      factory_test_stage = 8;
      break;
    case 8: // DO3
      ISet_DO_Break(DO_CHN_2);
      ISet_DO_Through(DO_CHN_3);
      factory_test_stage = 9;
      break;
    case 9: // DO4
      ISet_DO_Break(DO_CHN_3);
      ISet_DO_Through(DO_CHN_4);
      factory_test_stage = 10;
      break;
    case 10: // DO5
      ISet_DO_Break(DO_CHN_4);
      ISet_DO_Through(DO_CHN_5);
      factory_test_stage = 11;
      break;
    case 11: // DO6
      ISet_DO_Break(DO_CHN_5);
      ISet_DO_Through(DO_CHN_6);
      factory_test_stage = 17;
      break;
    case 17: //
      factory_timeout++;
      if (factory_timeout >= 11)
      {
				 ISet_DO_Break(DO_CHN_6);
       // HAL_PWM_SetPercent(TO_CHN_3, 0);
        cmpr_req.cmpr_rps = 15;//HoldingReg[HR_CMPR_FRQ_MIN];
        cmpr_req.cmpr_target = 15;
        cmpr_req.fan_1_rpm = 0;
        cmpr_req.fan_2_rpm = 0;
        factory_test_stage = 18;
        factory_timeout = 0;
      }
      break;
    case 18: //
      factory_timeout++;
      if (factory_timeout >= 10)
      {
        if (cmpr_ack.cmpr_rps < 5) 
        {
          factory_test_error = 9;
          factory_test_stage = 255;
          cmpr_req.fan_1_rpm = 0;
        }
        else
        {
          cmpr_req.fan_1_rpm = 72;
          factory_test_stage = 19;
        }
        factory_timeout = 0;
        cmpr_req.cmpr_rps = 0;
        cmpr_req.cmpr_target = 0;
        cmpr_req.fan_2_rpm = 0;
      }
      break;
    case 19: //
      factory_timeout++;
      if (factory_timeout >= 15)
      {
        if (cmpr_ack.fan_1_rpm < 200) 
        {
          factory_test_error = 10;
          factory_test_stage = 255;
          cmpr_req.fan_2_rpm = 0;
        }
        else
        {
					cmpr_req.fan_2_rpm = 72;
					factory_test_stage = 20;
        }
        factory_timeout = 0;
        cmpr_req.cmpr_rps = 0;
        cmpr_req.cmpr_target = 0;
        cmpr_req.fan_1_rpm = 0;
      }
      break;
    case 20:
      factory_timeout++;
      if (factory_timeout >= 15)
      {
        if (cmpr_ack.fan_2_rpm < 200) 
        {
          factory_test_error = 11;
          factory_test_stage = 255;
        }
        else
        {
          factory_test_stage = 21;
        }
        factory_timeout = 0;
        cmpr_req.cmpr_rps = 0;
        cmpr_req.cmpr_target = 0;
        cmpr_req.fan_1_rpm = 0;
        cmpr_req.fan_2_rpm = 0;
      }
      break;
    case 21:
    case 127:
			if(GetJDASDParamValue(HREG_FACTORY_TEST_FLAG) != FACTORY_TEST_TAG)
			{
				IStore_Value(HREG_FACTORY_TEST_FLAG * 2, FACTORY_TEST_TAG);   
				SetJDASDParamValue(HREG_FACTORY_TEST_FLAG, FACTORY_TEST_TAG);
			
			}
      break;
    case 255:break;
    default:break;
  }
}

void UpdateCompOutput()
{
	if (GetJDASDParamValue(HREG_TEST_FLAG) == 1)
  {
		if(InputReg[REG_ERROR_CODE]!=0 && CMPR_Cmd == ST_STOP)
		{
			cmpr_req.cmpr_target = 0;
			cmpr_speed = cmpr_req.cmpr_target;
			InputReg[REG_CMPR_WRITE] = cmpr_req.cmpr_target;
		}
		else
		{
			if(CMPR_Cmd == ST_RUN)
			{
				cmpr_speed = GetJDASDParamValue(HREG_TEST_SPEED);
				InputReg[REG_CMPR_WRITE] = GetJDASDParamValue(HREG_TEST_SPEED);
			}
		}
  }
  else
  {
    cmpr_speed = cmpr_req.cmpr_target;
    InputReg[REG_CMPR_WRITE] = cmpr_req.cmpr_target;
  }
	if(cmpr_speed != Last_cmpr_speed)
	{
		ModbusRTU_Master_WriteSlave_SingleValue(	1	,	6	,	COMP_SPEED_ADD	,cmpr_speed);

	}
	Last_cmpr_speed = cmpr_speed;

}

void UpdateFanOutput()
{	
  if (GetJDASDParamValue(HREG_TEST_FLAG) == 1)
  {
    if(InputReg[REG_ERROR_CODE]!=0 && CMPR_Cmd == ST_STOP)
		{
			fan_speed[0] = 0;
			InputReg[REG_FAN1_WRITE] = fan_speed[0];
			fan_speed[1] = 0;
			InputReg[REG_FAN2_WRITE] = fan_speed[1];
		}
		else
		{
			if(delay_fan1_trm.ticks != 0 || delay_fan2_trm.ticks != 0)
			{
				fan_speed[0] = 0;
				InputReg[REG_FAN1_WRITE] = fan_speed[0];
				fan_speed[1] = 0;
				InputReg[REG_FAN2_WRITE] = fan_speed[1];
			}
			else
			{
				if(CMPR_Cmd == ST_RUN)
				{
					if(fan1_err_times == 1 || fan2_err_times == 1)
					{
						cmpr_req.fan_1_rpm = 50;
						cmpr_req.fan_2_rpm = 50;
					}
					fan_speed[0] = GetJDASDParamValue(HREG_TEST_FAN1_SPEED) * 10;
					InputReg[REG_FAN1_WRITE] = fan_speed[0];
					fan_speed[1] = GetJDASDParamValue(HREG_TEST_FAN2_SPEED) * 10;
					InputReg[REG_FAN2_WRITE] = fan_speed[1];
				}
			}
		}
  }
  else
  {
		if(delay_fan1_trm.ticks != 0 || delay_fan2_trm.ticks != 0)
		{
			fan_speed[0] = 0;
			InputReg[REG_FAN1_WRITE] = fan_speed[0];
			fan_speed[1] = 0;
			InputReg[REG_FAN2_WRITE] = fan_speed[1];
		}
		else
		{
			if(fan1_err_times == 1 || fan2_err_times == 1)
			{
				cmpr_req.fan_1_rpm = 50;
				cmpr_req.fan_2_rpm = 50;
			}
			fan_speed[0] = cmpr_req.fan_1_rpm * 10;
			InputReg[REG_FAN1_WRITE] = fan_speed[0];
			fan_speed[1] = cmpr_req.fan_2_rpm * 10;
			InputReg[REG_FAN2_WRITE] = fan_speed[1];
		}
  }
	
	if(fan_speed[0] != Last_fan_speed[0])
	{
		Set_AimSpeed(0, fan_speed[0]);
		
	
	}
	Last_fan_speed[0] = fan_speed[0];
	
	if(fan_speed[1] != Last_fan_speed[1])
	{
		Set_AimSpeed(1, fan_speed[1]);
		
	}
	 Last_fan_speed[1] = fan_speed[1];

}

void UpdateElecVale(void)
{
//	if (GetJDASDParamValue(HREG_TEST_FLAG) == 1)
//	{
//		EEValveState.pos_out = GetJDASDParamValue(HREG_ELV_STEP);
//	}
//	else
//	{
//		EEValveState.pos_out = EEValveState.pos_set;
//	}
	
	EEValveState.pos_out = EEValveState.pos_set;
	InputReg[REG_EXV_STEP] = ElectricValve.Step;
	InputReg[REG_EXV_ADJ] = ElectricValve.Adjust;
	InputReg[REG_EXV_PULSE] = ElectricValve.Pulse;
	InputReg[REG_TO_EEV_SET]= EEValveState.pos_out;
	ISet_EXV_Value(InputReg[REG_TO_EEV_SET]);
	
}

void Device_GetInputValue(void)
{
  float press;
//  float temp;
    
  //Digital Input
  InputReg[REG_DI_CMPR_RUN_ST]= IGet_DI_State	(DI_CMPR_RUN);
	InputReg[REG_DI_LO_PRESS_ST]= IGet_DI_State	(DI_LO_PRESS);
	InputReg[REG_DI_HI_PRESS_ST]= IGet_DI_State	(DI_HI_PRESS) ^ 1; 
  InputReg[REG_DI_REMOTE_ON_ST]= IGet_DI_State(DI_REMOTE_ON); 
  
	if(InputReg[REG_TEMP_DISCHG] > IGet_AI_Scaled_Value(ADC_CHN_T1))
	{
		td_rise_flag = 2;
	}
	else if(InputReg[REG_TEMP_DISCHG] < IGet_AI_Scaled_Value(ADC_CHN_T1))
	{
		td_rise_flag = 1;
	}
	else
	{
		td_rise_flag = 0;
	}
  InputReg[REG_TEMP_DISCHG]= IGet_AI_Scaled_Value(ADC_CHN_T1);
  InputReg[REG_TEMP_SUCTION]= IGet_AI_Scaled_Value(ADC_CHN_T2);
  InputReg[REG_TEMP_OUTDOOR]= IGet_AI_Scaled_Value(ADC_CHN_T3);

  press= Press_GetGagePress(AI_LO_PRESS);
  if(press > -9990 && press < 9990)
  {
    InputReg[REG_TEMP_EVAPORATION]= Sensor_PressureToTemperature(press + 101, R410A);    //Te
   // press*= 100;
  }
  else
  {
    InputReg[REG_TEMP_EVAPORATION] = 9999;
  }
  InputReg[REG_PRESS_SUCTION]= press;
  
  press= Press_GetGagePress(AI_HI_PRESS);
  if(press > -9990 && press < 9990)
  {
    InputReg[REG_TEMP_CONDENSITION]= Sensor_PressureToTemperature(press + 101, R410A);  //Tc
    //press*= 100;
  }
  else
  {
    InputReg[REG_TEMP_CONDENSITION] = 9999;
  }
  InputReg[REG_PRESS_DISCHG]= press;
  InputReg[REG_TdSH] = InputReg[REG_TEMP_DISCHG] - InputReg[REG_TEMP_CONDENSITION];
  InputReg[REG_TsSH] = InputReg[REG_TEMP_SUCTION] - InputReg[REG_TEMP_EVAPORATION];
  //Software Point for Test
  InputReg[REG_ADC_P1]= IGet_AD_Value(AI_LO_PRESS);
  InputReg[REG_ADC_P2]= IGet_AD_Value(AI_HI_PRESS);
  //InputReg[REG_ADC_P3]= IGet_AD_Value(AI_BK_PRESS);
  InputReg[REG_ADC_REF]= IGet_AD_Value(ADC_CHN_REF);
  InputReg[REG_COMPRESSOR_STATE] = CMPR_State;
  InputReg[REG_OILCOLLECT_STAGE] = oil_collect_state;
	InputReg[REG_OC_STAGE] = oilCol.stage;
  InputReg[REG_OC_WAIT_COUNT] = oilCol.wait_count;
  InputReg[REG_OC_CANCEL_COUNT] = oilCol.cancel_count;
  InputReg[REG_OC_STAGE_DELAY] = oilCol.stage_delay;
  InputReg[REG_WAIT_START] = wait_start_delay;
  InputReg[REG_WAIT_STOP] = wait_stop_delay;
  InputReg[REG_PROTECT_START] = protect_start_delay;
  InputReg[REG_PROTECT_STOP] = protect_stop_delay;
}


void Oil_Collect_Progress(uint8_t tick)
{
  if (InputReg[REG_CMPR_START] == 0)
  {
    oilCol.cancel_count = 0;
  }

  if (oil_collect_state)
  {
    CmprPID.delay = 0;
    if (InputReg[REG_PRESS_SUCTION] < 20)
    {
      oil_collect_state= 0;
      CMPR_State= ST_STOP;
      CMPR_Cmd= ST_STOP;
      InputReg[REG_CMPR_START] = 0;
      CmprPID.output = 0;
      return;
    }
    switch (oil_collect_state)
    {
      case 1:
        CMPR_State = ST_STOP;
        CMPR_Cmd = ST_STOP;
        cmpr_req.cmpr_rps = 0;
        InputReg[REG_CMPR_START]= 0;
        if (cmpr_ack.cmpr_rps == 0)
        {
          if(protect_start_delay || protect_stop_delay)
          {
          }
          else
          {
            oil_collect_state = 2;
          }
        }
        break;
      case 2:
        oil_collect_state = 3;
        CMPR_State = ST_RUN;
        CMPR_Cmd = ST_RUN;
        cmpr_req.cmpr_rps = 30;
        InputReg[REG_CMPR_START] = 1;
        Delay_Start(&delay_oil_collect_30);
        break;
      case 3: // 50Hz
        cmpr_req.cmpr_rps = 30;
        if (delay_oil_collect_30.state)
        {
          oil_collect_state = 4;
          cmpr_req.cmpr_rps = GetJDASDParamValue(HREG_OIL_COL_OP_FQ); 
          Delay_Stop(&delay_oil_collect_30);
          oilCol.stage_delay = GetJDASDParamValue(HREG_OIL_COL_OP_S); 
        }
        break;
      case 4: // 30Hz
        cmpr_req.cmpr_rps = GetJDASDParamValue(HREG_OIL_COL_OP_FQ);  
        if (oilCol.stage_delay > 0)
        {
          oilCol.stage_delay -= tick;
        }
        else
        {
          oil_collect_state = 5;
          cmpr_req.cmpr_rps = 30;
          Delay_Start(&delay_oil_collect_3);                                          
        }
        break;
      case 5: // 30Hz
        cmpr_req.cmpr_rps = 30;
        if (delay_oil_collect_3.state)
        {
          oil_collect_state = 0;
          CMPR_State= ST_RUN;
          CMPR_Cmd= ST_RUN;
          InputReg[REG_CMPR_START] = 1;
          CmprPID.output = 30;
          Delay_Stop(&delay_oil_collect_3);
        }
        break;
    }
  }
  else
  {
    if (InputReg[REG_REQUIRE_RPS] <= GetJDASDParamValue(HREG_OIL_COL_WT_FQ)  && InputReg[REG_CMPR_START])
    {
      if (oilCol.wait_count < (GetJDASDParamValue(HREG_OIL_COL_WT_M) * 60))
      {
        oilCol.wait_count += tick;
      }
      else
      {
        if (oil_collect_state == 0)
        {
          oil_collect_state= 1;
          oilCol.wait_count = 0;
          protect_stop_delay = 210;
        }
      }
    }
    else if (InputReg[REG_REQUIRE_RPS] >= GetJDASDParamValue(HREG_OIL_COL_RE_HZ) )
    {
      if (oilCol.cancel_count < GetJDASDParamValue(HREG_OIL_COL_RE_S))
      {
        oilCol.cancel_count += tick;
      }
      else
      {
        oilCol.wait_count = 0;
        oilCol.cancel_count = 0;
      }
    }
    else
    {
      oilCol.cancel_count = 0;
    }
  }
}

void Device_ExpansionValve_Init(void)
{
  EEValveState.state= ST_STOP;
	EEValveState.sta_cycl = 0;
  EEValveState.pos_step= 5;
  EEValveState.pos_set= 0;
	ValveInitial();
  
//  Timer_Init(&tm_eev, 1, 1000);    // 1s 
//  Timer_Start(&tm_eev);
}


void Device_CMPR_PID_Init(void)
{
  float kp, ki, kd, base;
  
  kp = GetJDASDParamValue(HREG_CMPR_PID_P);//HoldingReg[HR_CMPR_PID_P];
  ki = GetJDASDParamValue(HREG_CMPR_PID_I);//HoldingReg[HR_CMPR_PID_I];
  kd = GetJDASDParamValue(HREG_CMPR_PID_D);//HoldingReg[HR_CMPR_PID_D];
  kp/= 100;
  ki/= 100;
  kd/= 100;
  base = GetJDASDParamValue(HREG_CMPR_FRQ_INIT)  / up_limit_frequence ;
  PID_Init(&CmprPID, kp, ki, kd, 1, base);
  
//  Timer_Init(&tm_pid, 1, 1000);    // 1s 
//  Timer_Start(&tm_pid);
}


// Compressor Heater Control
// Compressor ON, Heater OFF.
// Compressor OFF, Heater ON.
void Device_CMPR_Heater(void)
{
	if(CMPR_Cmd== ST_RUN || CMPR_Cmd== ST_INIT)
	{
		ASDPack.SysStatus = STATUS_AUTO;
	}
	
  if(InputReg[REG_DI_REMOTE_ON_ST] && InputReg[REG_TEMP_OUTDOOR] > -3000
				&& ASDPack.SysStatus != STATUS_AUTO)
  {
		if(InputReg[REG_TEMP_OUTDOOR] < GetJDASDParamValue(HREG_HEATE_TEMP)*10)
		{
			if(delay_heater.start == 0)
			{
				InputReg[REG_DO_CMPR_HTR]= 1;
				ISet_DO_Through(DO_CMPR_HTR);
				Delay_Start(&delay_heater);
			}
		}
		else if(start_delay>0)
		{
			Delay_Stop(&delay_heater);
			delay_heater.over = 0;
		}
  }
  
	if(delay_heater.state || InputReg[REG_TEMP_OUTDOOR] > GetJDASDParamValue(HREG_HEATE_TEMP)*10 + 20
		|| (GetJDASDParamValue(HREG_TEST_FLAG)==1 && InputReg[REG_CMPR_FRQ]>0))
  {
    InputReg[REG_DO_CMPR_HTR]= 0;
		ISet_DO_Break(DO_CMPR_HTR);
		delay_heater.over = 1;
  }
	
//	if(InputReg[REG_TEMP_OUTDOOR] < GetJDASDParamValue(HREG_HEATE_TEMP)*10)
//	{
//		delay_heater.over = 0;
//	}
	
}


// Expansion Valve Control TdSH
void Device_ExpansionValve(void)
{
  if(InputReg[REG_CMPR_START] || oil_collect_state > 1)
  {
    switch(EEValveState.state)
    {
      case ST_STOP:
        if(InputReg[REG_TEMP_DISCHG] >600)  //Td > 60, Open 5% for 1 minute
        {
          EEValveState.pos_set= 5;
          Delay_Start(&delay_eev_init);  //Last for 60s
          
          EEValveState.state= ST_INIT;
        }
        break;
      case ST_INIT:
        if(delay_eev_init.state)
        {
          Delay_Stop(&delay_eev_init);
          EEValveState.state= ST_RUN;
        }
        break;
      case ST_RUN:
        //TdSH
        if(Device_Error.pd_flt || Device_Error.td_flt)    //Pd Sensor Fault || Td Sensor Fault
        {
          EEValveState.pos_set= 10;
        }
        else
        {
          if(ASDPack.tm_tdsh_cycle_sec == 0)
          {
            if(InputReg[REG_TdSH] > 350)
            {
              EEValveState.pos_set+= EEValveState.pos_step;
              if(EEValveState.pos_set > 100)
              {
                EEValveState.pos_set= 100;
              }
            }
            else
            {
              if(InputReg[REG_TdSH] < 250)
              {
                if(EEValveState.pos_set> EEValveState.pos_step)
                {
                  EEValveState.pos_set-= EEValveState.pos_step;
                }
                else
                {
                  EEValveState.pos_set= 0;
                }
              }
            }
						ResetCapacityTimer(TM_TDSH_CYCLE_SEC,0);	
          }
        }
        break;
    }
  }
  else
  {
    EEValveState.state= ST_STOP;
  }
  
  if(EEValveState.state== ST_STOP)
  {
    EEValveState.pos_set= 0;
    Delay_Stop(&delay_eev_init);
  }
  
	if(InputReg[HREG_TEST_FLAG] == 0) 
	{
		InputReg[REG_TO_EEV_SET]= EEValveState.pos_set;
		AdjustValveAbs(EEValveState.pos_set);
	}
}
void writeErrorToFlash(uint16_t v) 
{
  uint16_t c = InputReg[REG_ERROR_RECORD_COUNT];
  c = c % 15;
  c += IR_ERROR_RECORD_1;
  InputReg[c] = v;
  InputReg[REG_ERROR_RECORD_COUNT]++;
/*  HoldingReg[c + 60] = v;
  HAL_EEPROM_SaveToCache(&HoldingReg[0], c, v, 32767, 0);
  if(HAL_EEPROM_IsModified())
  {
    HAL_EEPROM_Save(HR_ERROR_RECORD_COUNT, &HoldingReg[HR_ERROR_RECORD_COUNT], 16);
  }*/
}

void stack(uint8_t value,uint8_t* data,uint8_t size)
{
	uint8_t i=0;
	for(i=1;i<size;i++)
	{
		data[size-i] = data[size-i-1];
	}
	data[0] = value;
}

/////////////////////////////////////////////////////////////////////////////////////////
// ERROR
uint8_t Device_ExceptionStatus(ERROR_BIT *err, uint8_t tick)
{
	int8_t i, errorCd;
	
	//L1. E20 DI Low Press
  if(InputReg[REG_DI_LO_PRESS_ST])
  {
    if(err->di_lo== 0)
    {
      err->di_lo= 1;
      errorState[ERR_DI_LO] = 1;
			stack(ERR_DI_LO,levela_error,2);
      fail_to_restart= 1800;
    }
  }
  else
  {
    err->di_lo= 0;
    errorState[ERR_DI_LO] = 0;
  }
	
	//L1. E18 pd low
  if (err->pd_flt == 0)
  {
    if (InputReg[REG_PRESS_DISCHG] < 50) // 0.5bar
    {
      if (delay_pd_lo < 1200) // 20min
      {
        delay_pd_lo += tick;
      }
      else
      {
				if(err->pd_lo == 0)
				{
					err->pd_lo= 1;
					errorState[ERR_PD_LO] = 1;
					stack(ERR_PD_LO,levela_error,2);
					CMPR_Cmd= ST_STOP;
					delay_pd_lo = 0;
				}
      }
    }
    else
    {
      delay_pd_lo = 0;
      err->pd_lo = 0;
      errorState[ERR_PD_LO] = 0;
    }
  }
  else
  {
    err->pd_lo = 0;
    errorState[ERR_PD_LO] = 0;
    delay_pd_lo = 0;
  }
	
	//L2. E19 DI High Press
  if(InputReg[REG_DI_HI_PRESS_ST])
  {
    if(err->di_hi== 0)
    {
      err->di_hi= 1;
      errorState[ERR_DI_HI] = 1;
			stack(ERR_DI_HI,levelb_error,2);
			CMPR_Cmd= ST_STOP;
      fail_to_restart= 480;
    }
  }
  else
  {
    err->di_hi= 0;
    errorState[ERR_DI_HI] = 0;
  }
	
	//L2. E12 Low Frequency Hi Pd
  if(InputReg[REG_CMPR_FRQ] <= 30 && InputReg[REG_PRESS_DISCHG] >= 3400)
  {
		if(CMPR_Cmd!=ST_STOP)
    {
			Delay_Start(&delay_freq_lo_pd_hi);

			if(err->fr_lo_pe_hi== 0 && delay_freq_lo_pd_hi.state)
			{
				err->fr_lo_pe_hi= 1;
				errorState[ERR_FRQ_LO_PD_HI] = 1;
				stack(ERR_FRQ_LO_PD_HI,levelb_error,2);
				CMPR_Cmd= ST_STOP;
				fail_to_restart= 480;
				Delay_Stop(&delay_freq_lo_pd_hi);
			}
		}
  }
	else
	{
		Delay_Stop(&delay_freq_lo_pd_hi);
		err->fr_lo_pe_hi= 0;
		errorState[ERR_FRQ_LO_PD_HI] = 0;
	}
	
	
	//L3. E01 Communication
  if (cmpr_ack.cmpr_ack_ot_times >= 30)
  {
		if(err->comm == 0)
		{
			err->comm= 1;
			errorState[ERR_COMM] = 1;
			stack(ERR_COMM,levelc_error,20);
			CMPR_Cmd= ST_STOP;
		}
  }
  else
  {
    err->comm= 0;
    errorState[ERR_COMM] = 0;
  }
	
	//L3. E06 Pd high
	if (InputReg[REG_PRESS_DISCHG] < 9990 && InputReg[REG_PRESS_DISCHG] >= (GetJDASDParamValue(HREG_PD_HIGH_STOP) * 10))
  {
    if (CMPR_Cmd!= ST_STOP)
    {
      if(err->pd_flt== 0)
      {
        err->pd_hi= 1;
        errorState[ERR_PD_HI] = 1;
				stack(ERR_PD_HI,levelc_error,20);
				CMPR_Cmd = ST_STOP;
      }
    }
  }
	else
	{
		err->pd_hi= 0;
		errorState[ERR_PD_HI] = 0;
	}
		
	//L3. E08. Ps Low, Ps < A, last for 3 sec. A:Stop Ps
  if(InputReg[REG_PRESS_SUCTION] > -9990 && InputReg[REG_PRESS_SUCTION] <= GetJDASDParamValue(HREG_PS_CMPR_STOP))
  {
    if(err->ps_flt== 0 && (CMPR_Cmd!=ST_STOP))
    {
      Delay_Start(&delay_ps_lo);
    }
    else
    {
      Delay_Stop(&delay_ps_lo);
    }
    
    if(err->ps_lo== 0 && delay_ps_lo.state)
    {
      Delay_Stop(&delay_ps_lo);
      err->ps_lo= 1;
      errorState[ERR_PS_LO] = 1;
			stack(ERR_PS_LO,levelc_error,20);
			CMPR_Cmd = ST_STOP;
    }
  }
  else
  {
    err->ps_lo= 0;
    errorState[ERR_PS_LO] = 0;
    Delay_Stop(&delay_ps_lo);
  }
	
	//L3. E09 Td > 120, Td Hi, Td > 120
  if(InputReg[REG_TEMP_DISCHG] < 9990 && InputReg[REG_TEMP_DISCHG] >= GetJDASDParamValue(HREG_TD_HIGH_STOP) *10)  
  {
    if(err->td_flt== 0 && CMPR_Cmd!= ST_STOP)
    {
      Delay_Start(&delay_td_hi);
    }
		
    if(delay_td_hi.state && err->td_hi == 0)
    {
      Delay_Stop(&delay_td_hi);
      err->td_hi= 1;
      errorState[ERR_TD_HI] = 1;
			stack(ERR_TD_HI,levelc_error,20);
			CMPR_Cmd = ST_STOP;
      Delay_Start(&td_hi_err_reset);
    }
  }
  else
  {
		if(td_hi_err_reset.state)
		{
			err->td_hi= 0;
			errorState[ERR_TD_HI] = 0;
			Delay_Stop(&delay_td_hi);
			Delay_Stop(&td_hi_err_reset);
		}
  }
	
	//L3. E10 Td < 10
	if(InputReg[REG_TEMP_DISCHG] < GetJDASDParamValue(HREG_TD_LOW_AL))
  {
    if(err->td_flt== 0 && CMPR_Cmd!= ST_STOP)
    {
      if (delay_td_lo < GetJDASDParamValue(HREG_TD_LOW_DL))
      {
        delay_td_lo += tick;
      }
      else
      {
        if (err->td_lo == 0)
        {
          err->td_lo= 1;
          errorState[ERR_TD_LO] = 1;
					stack(ERR_TD_LO,levelc_error,20);
					CMPR_Cmd = ST_STOP;
          fail_to_restart= 480;
          delay_td_lo = 0;
        }
      }
    }
    else
    {
      delay_td_lo = 0;
      err->td_lo= 0;
    }
  }
  else
  {
    delay_td_lo = 0;
    err->td_lo= 0;
    errorState[ERR_TD_LO] = 0;
  }
	
	//L3. E11 TsSH < 10
	if(InputReg[REG_TsSH] <= 0 && !delay_cmpr_init.start)
  {
    if(err->ts_flt== 0 && err->ps_flt== 0 && CMPR_Cmd!= ST_STOP)
    {
      Delay_Start(&delay_tssh_lo);
    }
		else
		{
			Delay_Stop(&delay_tssh_lo);
		}
    
    if(delay_tssh_lo.state && err->tdsh_lo == 0)
    {
      Delay_Stop(&delay_tssh_lo);
      err->tdsh_lo= 1;
      errorState[ERR_TSSH_LO] = 1;
			stack(ERR_TSSH_LO,levelc_error,20);
			CMPR_Cmd = ST_STOP;
    }
  }
  else
  {
    Delay_Stop(&delay_tssh_lo);
    err->tdsh_lo= 0;
    errorState[ERR_TSSH_LO] = 0;
  }
	
	//L3.  E13 Driver 
	if(cmpr_ack.error_codeL == 1)
  {
		if(err->hac_hi == 0)
		{
			err->hac_hi= 1;
			errorState[ERR_HARDAC_HI] = 1;
			stack(ERR_HARDAC_HI,levelc_error,20);
			CMPR_Cmd = ST_STOP;
			cmpr_error= 1;
		}
  }
  else
  {
    err->hac_hi= 0;
    errorState[ERR_HARDAC_HI] = 0;
  }
	
	//L3. E14 Driver
	if(cmpr_ack.error_codeL == 2)
  {
		if(err->sac_hi == 0)
		{
			err->sac_hi= 1;
			errorState[ERR_SOFTAC_HI] = 1;
			stack(ERR_SOFTAC_HI,levelc_error,20);
			CMPR_Cmd = ST_STOP;
			cmpr_error= 1;
		}
  }
  else
  {
    err->sac_hi= 0;
    errorState[ERR_SOFTAC_HI] = 0;
  }
	
	//L3. E15 Driver AC Under Voltage
  //if(cmpr_ack.pfc_code & CMPR_ERR_AC_UV)
	if(cmpr_ack.error_codeL == 3)
  {
		if(err->ac_uv == 0)
		{
			err->ac_uv= 1;
			errorState[ERR_AC_UV] = 1;
			stack(ERR_AC_UV,levelc_error,20);
			CMPR_Cmd = ST_STOP;
			cmpr_error= 1;
		}
  }
  else
  {
    err->ac_uv= 0;
    errorState[ERR_AC_UV] = 0;
  }
	
	
  //L3. E16 Driver AC Over Voltage
 // if(cmpr_ack.pfc_code & CMPR_ERR_AC_OV)
	if(cmpr_ack.error_codeL == 4)
  {
		if(err->ac_ov == 0)
		{
			err->ac_ov= 1;
			errorState[ERR_AC_OV] = 1;
			stack(ERR_AC_OV,levelc_error,20);
			CMPR_Cmd = ST_STOP;
			cmpr_error= 1;
		}
  }
  else
  {
    err->ac_ov= 0;
    errorState[ERR_AC_OV] = 0;
  }
  
	//L3. E17 Driver IPM temp hight
	if(cmpr_ack.error_codeL == 9)
  {
		if(err->trsipm_hi == 0)
		{
			err->trsipm_hi= 1;
			errorState[ERR_TRSIPM_HI] = 1;
			stack(ERR_TRSIPM_HI,levelc_error,20);
			CMPR_Cmd = ST_STOP;
			cmpr_error= 1;
		}
  }
  else
  {
    err->trsipm_hi= 0;
    errorState[ERR_TRSIPM_HI] = 0;
  }
	
	
	//L3. E21. Driver
	if(cmpr_ack.phase_curr >= GetJDASDParamValue(HREG_DC_HIGH_STOP))
  {
    if(err->dc_hi== 0 && CMPR_Cmd!= ST_STOP)
    {
      err->dc_hi= 1;
      errorState[ERR_DC_HI] = 1;
			stack(ERR_DC_HI,levelc_error,20);
			CMPR_Cmd = ST_STOP;
      fail_to_restart= 480;
    }
  }
  else
  {
    err->dc_hi= 0;
    errorState[ERR_DC_HI] = 0;
  }
	
	//L3. E22 Ipm temp hight
  if(cmpr_ack.temp_ipm >= GetJDASDParamValue(HREG_IPM_HIGH_STOP) *10)
  {
		if(CMPR_Cmd!= ST_STOP)
		{
			Delay_Start(&delay_ipm_temp_hi);
		}
		
    if(delay_ipm_temp_hi.state && err->imp_hi == 0)
    {
      err->imp_hi= 1;
      errorState[ERR_IPM_HI] = 1;
			stack(ERR_IPM_HI,levelc_error,20);
			CMPR_Cmd = ST_STOP;
      fail_to_restart= 480;
			Delay_Stop(&delay_ipm_temp_hi);
    }
  }
  else
  {
		Delay_Stop(&delay_ipm_temp_hi);
    err->imp_hi= 0;
    errorState[ERR_IPM_HI] = 0;
  }
	
	//L3. E24 lk phase
	if(cmpr_ack.error_codeL == 5)
  {
		if(err->lk_phase==0)
		{
			err->lk_phase= 1;
			errorState[ERR_LK_PHASE] = 1;
			stack(ERR_LK_PHASE,levelc_error,20);
			CMPR_Cmd = ST_STOP;
			cmpr_error= 1;
		}
  }
  else
  {
    err->lk_phase= 0;
    errorState[ERR_LK_PHASE] = 0;
  }

	
	//L3. E25 Driver lk rotation
	if(cmpr_ack.error_codeL == 6)
  {
		if(err->lk_rot==0)
		{
			err->lk_rot= 1;
			errorState[ERR_LK_ROT] = 1;
			stack(ERR_LK_ROT,levelc_error,20);
			CMPR_Cmd = ST_STOP;
			cmpr_error= 1;
		}
  }
  else
  {
    err->lk_rot= 0;
    errorState[ERR_LK_ROT] = 0;
  }
	
	//L3. E26 Driver start protection
	if(cmpr_ack.error_codeL == 7)
  {
		if(err->st_proc==0)
		{
			err->st_proc= 1;
			errorState[ERR_ST_PROC] = 1;
			stack(ERR_ST_PROC,levelc_error,20);
			CMPR_Cmd = ST_STOP;
			cmpr_error= 1;
		}
  }
  else
  {
    err->st_proc= 0;
    errorState[ERR_ST_PROC] = 0;
  }

	
	//L3. E27 voltage protection
	if(cmpr_ack.error_codeL == 11)
  {
		if(err->vol_proc==0)
		{
			err->vol_proc = 1;
			errorState[ERR_VOL_PROC] = 1;
			stack(ERR_VOL_PROC,levelc_error,20);
			CMPR_Cmd = ST_STOP;
			cmpr_error= 1;
		}
  }
  else
  {
    err->vol_proc= 0;
    errorState[ERR_VOL_PROC] = 0;
  }
	
	//L3 E28 风机1故障检测
	if(InputReg[REG_FAN1_WRITE] > 0)
	{
		Delay_Start(&delay_fan1_start);
		
		if (delay_fan1_start.state)
		{
			if (InputReg[REG_FAN_SP_1] < 20 || InputReg[REG_FAN_SP_1] >= 2550)
			{
				Delay_Start(&delay_fan1_fault);
				if(delay_fan1_fault.state)
				{
					fan1_err_times ++;
					Delay_Stop(&delay_fan1_fault);
					if(fan1_err_times == 1)
					{
						Delay_Start(&delay_fan1_trm);
					}
					if(fan1_err_times >=2)
					{
						//Delay_Stop(&delay_fan1_start);
						Delay_Stop(&delay_fan1_trm);
						Delay_Stop(&delay_fan1_fault);
						fan1_err_times = 0;
						err->fan1_ofc = 1;
						errorState[ERR_FAN1_OFC] = 1;
						stack(ERR_FAN1_OFC,levelc_error,20);
						CMPR_Cmd = ST_STOP;
						FanStart = 0;
					}
				}
			}
			else
			{
				if(err->fan1_ofc 
					&& (InputReg[REG_FAN_SP_1] > InputReg[REG_FAN1_WRITE]-20) 
						&& (InputReg[REG_FAN_SP_1] < InputReg[REG_FAN1_WRITE]+20))
				{
					Delay_Start(&delay_fan1_recover);
				}
				else
				{
					Delay_Stop(&delay_fan1_recover);
				}
				
				if(delay_fan1_recover.state)
				{
					Delay_Stop(&delay_fan1_fault);
					fan1_err_times = 0;
					err->fan1_ofc = 0;
					errorState[ERR_FAN1_OFC] = 0;
				}
			}
		}
	}
	else
	{
		Delay_Stop(&delay_fan1_start);
		Delay_Stop(&delay_fan1_fault);
	}

	if(delay_fan1_trm.state)
	{
		Delay_Stop(&delay_fan1_trm);
	}
		
	InputReg[REG_FAN_FAULT_TIMS] = fan1_err_times;
	
	
	//L3. E29 风机2故障检测
	if(InputReg[REG_FAN2_WRITE] > 0)
	{
		Delay_Start(&delay_fan2_start);
		
		if (delay_fan2_start.state)
		{
			if (InputReg[REG_FAN_SP_2] < 20 || InputReg[REG_FAN_SP_2] >= 2550)
			{
				Delay_Start(&delay_fan2_fault);
				if(delay_fan2_fault.state)
				{
					fan2_err_times++;
					Delay_Stop(&delay_fan2_fault);
					if(fan2_err_times==1)
					{
						Delay_Start(&delay_fan2_trm);
					}
					if(fan2_err_times >=2)
					{
						//Delay_Stop(&delay_fan2_start);
						Delay_Stop(&delay_fan2_fault);
						Delay_Stop(&delay_fan2_trm);
						fan2_err_times = 0;
						err->fan2_ofc = 1;
						errorState[ERR_FAN2_OFC] = 1;
						stack(ERR_FAN2_OFC,levelc_error,20);
						CMPR_Cmd = ST_STOP;
						FanStart = 0;
					}
				}
			}
			else
			{
				if(err->fan2_ofc 
					&& (InputReg[REG_FAN_SP_2] > InputReg[REG_FAN2_WRITE]-20) 
						&& (InputReg[REG_FAN_SP_2] < InputReg[REG_FAN2_WRITE]+20))
				{
					Delay_Start(&delay_fan2_recover);
				}
				else
				{
					Delay_Stop(&delay_fan2_recover);
				}
				
				if(delay_fan2_recover.state)
				{
					Delay_Stop(&delay_fan2_fault);
					fan2_err_times = 0;
					err->fan2_ofc = 0;
					errorState[ERR_FAN2_OFC] = 0;
				}
			}
		}
	}
	else
	{
		Delay_Stop(&delay_fan2_fault);
		Delay_Stop(&delay_fan2_start);
	}
	
	if(delay_fan2_trm.state)
	{
		Delay_Stop(&delay_fan2_trm);
	}
	
	if(CMPR_Cmd == ST_STOP)
	{
		Delay_Stop(&delay_fan1_fault);
		fan1_err_times = 0;
		err->fan1_ofc = 0;
		errorState[ERR_FAN1_OFC] = 0;
		
		Delay_Stop(&delay_fan2_fault);
		fan2_err_times = 0;
		err->fan2_ofc = 0;
		errorState[ERR_FAN2_OFC] = 0;
	}
	
	//L4. E02 排气压力传感器故障检测
  if((InputReg[REG_PRESS_DISCHG] <= -9990 || InputReg[REG_PRESS_DISCHG] >= 9990))
  {
    if (err->pd_flt == 0)
    {
      Delay_Start(&delay_pd_flt);
    }
    if (err->pd_flt == 0 && delay_pd_flt.state)
    {
      err->pd_flt= 1;
      errorState[ERR_PD_FAULT] = 1;
			stack(ERR_PD_FAULT,leveld_error,4);
			CMPR_Cmd = ST_STOP;
			FanStart = 0;
      Delay_Stop(&delay_pd_flt);
    }
  }
  else
  {
    err->pd_flt= 0;
    errorState[ERR_PD_FAULT] = 0;
    Delay_Stop(&delay_pd_flt);
  }
	
	//L4. E03 Ps Sensor Fault
  if((InputReg[REG_PRESS_SUCTION] <= -9990 || InputReg[REG_PRESS_SUCTION] >= 9990))
  {
    if (err->ps_flt == 0)
    {
      Delay_Start(&delay_ps_flt);
    }
    if (err->ps_flt == 0 && delay_ps_flt.state)
    {
      err->ps_flt= 1;
      errorState[ERR_PS_FAULT] = 1;
			stack(ERR_PS_FAULT,leveld_error,4);
			CMPR_Cmd = ST_STOP;
      Delay_Stop(&delay_ps_flt);
			
    }
  }
  else
  {
    err->ps_flt= 0;
    errorState[ERR_PS_FAULT] = 0;
    Delay_Stop(&delay_ps_flt);
  }
	
	//L4. E04 Td Sensor Fault
  if((InputReg[REG_TEMP_DISCHG] <= -3000) || (InputReg[REG_TEMP_DISCHG] >= 15000))
  {
		if (err->td_flt == 0)
    {
      Delay_Start(&delay_td_flt);
    }
    if (err->td_flt == 0 && delay_td_flt.state)
    {
			err->td_flt= 1;
			errorState[ERR_TD_FAULT] = 1;
			stack(ERR_TD_FAULT,leveld_error,4);
			CMPR_Cmd = ST_STOP;
      Delay_Stop(&delay_td_flt);
    }
  }
  else
  {
    err->td_flt= 0;
    errorState[ERR_TD_FAULT] = 0;
		Delay_Stop(&delay_td_flt);
  }
	
	//L4. E05 Ts Sensor Fault
  if((InputReg[REG_TEMP_SUCTION] <= -3000) || (InputReg[REG_TEMP_SUCTION] >= 10500))
  {
		if (err->ts_flt == 0)
    {
      Delay_Start(&delay_ts_flt);
    }
    if (err->ts_flt == 0 && delay_ts_flt.state)
    {
			err->ts_flt= 1;
			errorState[EER_TS_FAULT] = 1;
			stack(EER_TS_FAULT,leveld_error,4);
			CMPR_Cmd = ST_STOP;
      Delay_Stop(&delay_ts_flt);
    }
  }
  else
  {
    err->ts_flt= 0;
    errorState[EER_TS_FAULT] = 0;
		Delay_Stop(&delay_ts_flt);
  }
	
	//L5. E07. Ps Low, Ps < A, last for 3 sec. A:Stop Ps
	if (InputReg[REG_PRESS_SUCTION] >= GetJDASDParamValue(HREG_PS_HIGH_AL))
  {
    if(err->ps_flt== 0 && (CMPR_State!= STOP))
    {
      if (delay_ps_hi < GetJDASDParamValue(HREG_PS_HIGH_DL) * 6)
      {
        delay_ps_hi += tick;
      }
      else
      {
				if(err->ps_hi == 0)
				{
					err->ps_hi = 1;
					errorState[ERR_PS_HI] = 1;
					stack(ERR_PS_HI,levele_error,2);
					delay_ps_hi = 0;
				}
      }
    }
    else
    {
      delay_ps_hi = 0;
      err->ps_hi = 0;
      errorState[ERR_PS_HI] = 0;
    }
  }
  else
  {
    err->ps_hi = 0;
		delay_ps_hi = 0;
    errorState[ERR_PS_HI] = 0;
  }
	
	//L5. E23 Out Sensor Fault
  if((InputReg[REG_TEMP_OUTDOOR] <= -3000) || (InputReg[REG_TEMP_OUTDOOR] >= 11000))
  {
		if (err->os_flt == 0)
    {
      Delay_Start(&delay_os_flt);
    }
    if (err->os_flt == 0 && delay_os_flt.state)
    {
			err->os_flt= 1;
			errorState[ERR_OS_FAULT] = 1;
			stack(ERR_OS_FAULT,levele_error,2);
			WinterFlag = 0;
			//SetJDASDParamValue(HREG_WINTER_MODE, WinterFlag);
      Delay_Stop(&delay_os_flt);
    }
  }
  else
  {
    err->os_flt= 0;
    errorState[ERR_OS_FAULT] = 0;
		Delay_Stop(&delay_os_flt);
  }
  
  // Exception Alarm
  // Compressor Driver
  cmpr_error= 0;	 
	 
  if(err->comm== 0)
  {
    if(cmpr_error)
    {
      if(last_cmpr_error== 0)
      {
        if(++Error_CMPR_Err_Times > 30)
        {
          Error_CMPR_Err_Times= 30;
//          EmergencyFault= 1;
        }
        
        Delay_Start(&delay_cmpr_err_times_reset);
      }
    }
    else
    {
      if(last_cmpr_error)
      {
        Delay_Start(&delay_cmpr_err_times_reset);
      }

      if(delay_cmpr_err_times_reset.state && Error_CMPR_Err_Times < 30)
      {
        Delay_Stop(&delay_cmpr_err_times_reset);
        Error_CMPR_Err_Times= 0;
      }
    }
    
    last_cmpr_error= cmpr_error;
  }
  else
  {
		CMPR_Cmd= ST_STOP;
    cmpr_error= 0;
    last_cmpr_error= 0;
    Error_CMPR_Err_Times= 0;
    Delay_Stop(&delay_cmpr_err_times_reset);
  }
  
	for(i=0;i<2;i++)
	{
		errorCd = levela_error[i];
		if(errorCd != 0 && errorState[errorCd] != 0)
		{
			return errorCd;
		}
	}
	
	for(i=0;i<2;i++)
	{
		errorCd = levelb_error[i];
		if(errorCd != 0 && errorState[errorCd] != 0)
		{
			return errorCd;
		}
	}
	
	for(i=0;i<20;i++)
	{
		errorCd = levelc_error[i];
		if(errorCd != 0 && errorState[errorCd] != 0)
		{
			return errorCd;
		}
	}
	
	for(i=0;i<4;i++)
	{
		errorCd = leveld_error[i];
		if(errorCd != 0 && errorState[errorCd] != 0)
		{
			return errorCd;
		}
	}
	
	for(i=0;i<2;i++)
	{
		errorCd = levele_error[i];
		if(errorCd != 0 && errorState[errorCd] != 0)
		{
			return errorCd;
		}
	}
	
  if(InputReg[REG_ERROR_CODE] != 0)
	{
    Delay_Start(&delay_err_reset);
  }
  if (!delay_err_reset.start)
	{
    return 0;
  }
  if (delay_err_reset.state)
	{
    Delay_Stop(&delay_err_reset);
  }
	else
	{
    return InputReg[REG_ERROR_CODE];
  }
  return 0;
}


/////////////////////////////////////////////////////////////////////////////////////////
void Device_CMPR_StartStop(uint8_t tick)
{
  // Remote IO Start/Stop
  if(InputReg[REG_DI_REMOTE_ON_ST] && (InputReg[REG_DI_DEFROST_ST] == 0))
  {
    if(CMPR_State== ST_STOP && CMPR_Cmd== ST_STOP)
    {
      // Start Condition	
      // Te > Tset + dT/2, keep for 3 seconds
      if(InputReg[REG_PRESS_SUCTION] <= -9990 || InputReg[REG_PRESS_SUCTION] >= 9990
					|| InputReg[REG_PRESS_DISCHG] <= -9990 || InputReg[REG_PRESS_DISCHG] >= 9990
						|| InputReg[REG_TEMP_DISCHG] <= -3000 || InputReg[REG_TEMP_DISCHG] >= 15000
							|| InputReg[REG_TEMP_SUCTION] <= -3000 || InputReg[REG_TEMP_SUCTION] >= 10500)
      {
        Delay_Stop(&delay_cmpr_stop_on_fail);
        Delay_Start(&delay_cmpr_run_on_fail);
        if (delay_cmpr_run_on_fail.state)
				{
          CMPR_Cmd= ST_RUN;
					FanStart = 1;
        }
      }
      else
      {
        Delay_Stop(&delay_cmpr_stop_on_fail);
        Delay_Stop(&delay_cmpr_run_on_fail);
        if(InputReg[REG_TEMP_EVAPORATION] >GetJDASDParamValue(HREG_TEMP_EVP_SETPT)+GetJDASDParamValue(HREG_TEMP_DEADBAND_EVP)
					&& InputReg[REG_ERROR_CODE] != ERR_PD_HI && InputReg[REG_ERROR_CODE] != ERR_TD_HI)
        {
          if (wait_start_delay < GetJDASDParamValue(HREG_START_DELAY)) 
          {
            wait_start_delay += tick;
          }
          else
          {
            CMPR_Cmd= ST_RUN;
            wait_start_delay = 0;
          }
        }
        else
        {
          wait_start_delay = 0;
        }
        freq_low_stop_delay = 0;
      }
    }
    else if (CMPR_State== ST_RUN && CMPR_Cmd== ST_RUN)
    {
      if (InputReg[REG_CMPR_FRQ] <= GetJDASDParamValue(HREG_CMPR_FRQ_MIN)+3)
      {
        if (freq_low_stop_delay < GetJDASDParamValue(HREG_WAITSTOP_DELAY))
        {
          freq_low_stop_delay += tick;
        }
        else
        {
          CMPR_Cmd= ST_STOP;
          freq_low_stop_delay = 0;
        }
      }
      else if (InputReg[REG_CMPR_FRQ] > GetJDASDParamValue(HREG_CMPR_FRQ_MIN)+3)
      {
        freq_low_stop_delay = 0;
      }
			
      if(InputReg[REG_PRESS_SUCTION] <= -9990 || InputReg[REG_PRESS_SUCTION] >= 9990
					|| InputReg[REG_PRESS_DISCHG] <= -9990 || InputReg[REG_PRESS_DISCHG] >= 9990
						|| InputReg[REG_TEMP_DISCHG] <= -3000 || InputReg[REG_TEMP_DISCHG] >= 15000
							|| InputReg[REG_TEMP_SUCTION] <= -3000 || InputReg[REG_TEMP_SUCTION] >= 10500)
      {
        Delay_Stop(&delay_cmpr_run_on_fail);
        Delay_Start(&delay_cmpr_stop_on_fail);
        if (delay_cmpr_stop_on_fail.state) 
				{
          CMPR_Cmd= ST_STOP;
					FanStart  = 0;
        }
      }
      else
      {
        Delay_Stop(&delay_cmpr_stop_on_fail);
        Delay_Stop(&delay_cmpr_run_on_fail);
        if ((InputReg[REG_TEMP_EVAPORATION] <= GetJDASDParamValue(HREG_TEMP_EVP_SETPT)  - GetJDASDParamValue(HREG_TEMP_DEADBAND_DOWN)))
        {
          if (wait_stop_delay < GetJDASDParamValue(HREG_PS_LO_STOP_DL))
          {
            wait_stop_delay += tick;
          }
          else
          {
            CMPR_Cmd= ST_STOP;
            wait_stop_delay = 0;
          }
        }
        else
        {
          wait_stop_delay = 0;
        }
      }
    }
  }
  else
  {
    CMPR_Cmd= ST_STOP;
  }
  
  // Frequently Startup Protection
  if(Device_FrequentlyStartupProtect())
  {
    CMPR_Cmd= ST_STOP;
  }
	
	InputReg[REG_FAIL_RESTIME] = fail_to_restart;
  
  // Fail to Restart Delay
  if((fail_to_restart) || (InputReg[REG_DI_HI_PRESS_ST] == 1))
  {
    CMPR_Cmd= ST_STOP;
  }
  
  // Error Stop
  InputReg[REG_ERROR_CODE]= Device_ExceptionStatus(&Device_Error, tick);
  if (lastError != InputReg[REG_ERROR_CODE])
  {
    lastError = InputReg[REG_ERROR_CODE];
    if (lastError != 0)
    {
      writeErrorToFlash(lastError);
    }
  }

  // State Machine
  switch(CMPR_Cmd)
  {
    case ST_STOP:
      if(InputReg[REG_CMPR_START]== 0)
      {
        CMPR_State= ST_STOP;
      }
      break;
    case ST_INIT:
      if (oil_collect_state == 1 || oil_collect_state == 2)
      {
        CMPR_Cmd= ST_STOP;
        Delay_Stop(&delay_cmpr_init);
        break;
      }
      if (Device_Error.drv)
      {
        Delay_Restart(&delay_cmpr_init);
        break;
      }
      if(InputReg[REG_CMPR_START]
          && delay_cmpr_init.state)
      {
        Delay_Stop(&delay_cmpr_init);
        CMPR_State= ST_RUN;
        CMPR_Cmd= ST_RUN;
				CMPR_Start_Flag = 1;
      }
      break;
    case ST_RUN:
      if (oil_collect_state == 1 || oil_collect_state == 2)
      {
        break;
      }
      if(CMPR_State== ST_STOP)
      {
        Delay_Start(&delay_cmpr_init);
        CMPR_Cmd= ST_INIT;
      }
      break;
    default:
      break;
  }
}

uint8_t Device_CMPR_Freq_Hold(uint8_t freq, uint8_t freq_fb)
{
	uint8_t holdState = 0;
		
	if(GetJDASDParamValue(HREG_TEST_FLAG) == 1 || InputReg[REG_CMPR_START] == 0 || oil_collect_state > 0)
	{
		Delay_Stop(&delay_cmpr_hold);
		cmprOnSeconds = 0;
		InputReg[REG_POWERON_TIME] = cmprOnSeconds;
		cmpr_req.cmpr_freq_step = 0;
		return 0;
	}
	
	if(cmprOnSeconds >= 3600)
	{
		return 0;
	}
	
	switch(cmpr_req.cmpr_freq_step)
	{
		case 0:
			if(freq >= GetJDASDParamValue(HREG_FREQ_STEP1))
			{
				holdState = 1;
				if((control_State & CONTROL_SLOW_INCREASE) == 0x00)
				{
					if((control_State & CONTROL_FORCE_DECREASE) == 0x00)
					{
						cmpr_req.cmpr_rps = GetJDASDParamValue(HREG_FREQ_STEP1);
						cmpr_req.cmpr_target = cmpr_req.cmpr_rps;
					}
					else
					{
						holdState = 0;
					}
				}
				
				if(freq_fb >= GetJDASDParamValue(HREG_FREQ_STEP1)-1)
				{
					Delay_Start(&delay_cmpr_hold);
					if(delay_cmpr_hold.state)
					{
						cmpr_req.cmpr_freq_step = 1;
						Delay_Stop(&delay_cmpr_hold);
						holdState = 0;
					}
				}
				else
				{
					Delay_Pause(&delay_cmpr_hold);
				}

			}
			else
			{
				holdState = 0;
				Delay_Pause(&delay_cmpr_hold);
			}
			break;
		case 1:
			if(freq >= GetJDASDParamValue(HREG_FREQ_STEP2))
			{
				holdState = 1;
				if((control_State & CONTROL_SLOW_INCREASE) == 0x00)
				{
					if((control_State & CONTROL_FORCE_DECREASE) == 0x00)
					{
						cmpr_req.cmpr_rps = GetJDASDParamValue(HREG_FREQ_STEP2);
						cmpr_req.cmpr_target = cmpr_req.cmpr_rps;
					}
					else
					{
						holdState = 0;
					}
				}
				
				if(freq_fb >= GetJDASDParamValue(HREG_FREQ_STEP2)-1)
				{
					Delay_Start(&delay_cmpr_hold);
					if(delay_cmpr_hold.state)
					{
						cmpr_req.cmpr_freq_step = 2;
						Delay_Stop(&delay_cmpr_hold);
						holdState = 0;
					}
				}
				else
				{
					Delay_Pause(&delay_cmpr_hold);
				}
			}
			else
			{
				holdState = 0;
				Delay_Pause(&delay_cmpr_hold);
			}
			break;
		case 2:
			if(freq >= GetJDASDParamValue(HREG_FREQ_STEP3))
			{
				holdState = 1;
				if((control_State & CONTROL_SLOW_INCREASE) == 0x00)
				{
					if((control_State & CONTROL_FORCE_DECREASE) == 0x00)
					{
						cmpr_req.cmpr_rps = GetJDASDParamValue(HREG_FREQ_STEP3);
						cmpr_req.cmpr_target = cmpr_req.cmpr_rps;
					}
					else
					{
						holdState = 0;
					}
				}
				
				if(freq_fb >= GetJDASDParamValue(HREG_FREQ_STEP3)-1)
				{
					Delay_Start(&delay_cmpr_hold);
					if(delay_cmpr_hold.state)
					{
						cmpr_req.cmpr_freq_step = 3;
						Delay_Stop(&delay_cmpr_hold);
						holdState = 0;
					}
				}
				else
				{
					Delay_Pause(&delay_cmpr_hold);
				}
			}
			else
			{
				holdState = 0;
				Delay_Pause(&delay_cmpr_hold);
			}
			break;
		case 3:
		default:
			holdState = 0;
			Delay_Stop(&delay_cmpr_hold);
			break;
	}
	
	return holdState;
}

void Device_CMPR_FrequcyLimit(void)
{
  float fN1, fN2;

  control_State = 0;
  // Frequency Limit---------------------------------------------
  if(CMPR_State== ST_RUN)
  {
		 if((InputReg[REG_PRESS_DISCHG] >= -9990 && InputReg[REG_PRESS_DISCHG] <= 9990))
		 {
			//Forbid Pd/Ps
			cmpr_pd_ps_rate= InputReg[REG_PRESS_DISCHG];
			cmpr_pd_ps_rate/= InputReg[REG_PRESS_SUCTION];
			InputReg[REG_PS_PD_RATE]= cmpr_pd_ps_rate * 10;
			fN1= GetJDASDParamValue(HREG_PD_PS_N1);//HoldingReg[HR_PD_PS_N1];
			fN2= GetJDASDParamValue(HREG_PD_PS_N2);//HoldingReg[HR_PD_PS_N2];
			fN1/= 10;
			fN2/= 10;
			
			if(cmpr_pd_ps_rate < fN1)
			{
				Delay_Start(&delay_cmpr_pd_ps_lo);
				
				//Last for 5 mintes, Force Inc: 3Hz/s 
				if(delay_cmpr_pd_ps_lo.state)
				{
					cmpr_force_forbit.force_inc.bit.pdsr= 1;
				}
			}
			else
			{
				Delay_Stop(&delay_cmpr_pd_ps_lo);
				cmpr_force_forbit.force_inc.bit.pdsr= 0;
				
				if(cmpr_pd_ps_rate < fN2)
				{
					cmpr_force_forbit.forbit_dec.bit.pdsr= 1;
				}
				else
				{
					cmpr_force_forbit.forbit_dec.bit.pdsr= 0;
				}
			}
			
			if (InputReg[REG_PRESS_DISCHG] >= GetJDASDParamValue(HREG_PD_HIGH_UL) *10)
			{
				control_State |= CONTROL_FORCE_DECREASE;
			}
			else if (InputReg[REG_PRESS_DISCHG] >= GetJDASDParamValue(HREG_PD_HIGH_NI) *10)
			{
				control_State |= CONTROL_FORBID_INCREASER;
			}
			else if (InputReg[REG_PRESS_DISCHG] >= GetJDASDParamValue(HREG_PD_HIGH_SL) *10)
			{
				control_State |= CONTROL_SLOW_INCREASE;
			}
		}
    
    if (InputReg[REG_DC_CURRENT] >= GetJDASDParamValue(HREG_DC_HIGH_UL))
    {
      control_State |= CONTROL_FORCE_DECREASE;
    }
    else if (InputReg[REG_DC_CURRENT] >= GetJDASDParamValue(HREG_DC_HIGH_NI))
    {
      control_State |= CONTROL_FORBID_INCREASER;
    }
    else if (InputReg[REG_DC_CURRENT] >= GetJDASDParamValue(HREG_DC_HIGH_SL))
    {
      control_State |= CONTROL_SLOW_INCREASE;
    }
    
    if (InputReg[REG_TEMP_DISCHG] >= GetJDASDParamValue(HREG_TD_HIGH_UL) *10)
    {
      control_State |= CONTROL_FORCE_DECREASE;
    }
    else if (InputReg[REG_TEMP_DISCHG] >= GetJDASDParamValue(HREG_TD_HIGH_NI) *10)
    {
      control_State |= CONTROL_FORBID_INCREASER;
    }
    else if (InputReg[REG_TEMP_DISCHG] >= GetJDASDParamValue(HREG_TD_HIGH_SL) *10)
    {
      control_State |= CONTROL_SLOW_INCREASE;
    }
    
    if (InputReg[REG_TD_IPM] >= GetJDASDParamValue(HREG_IPM_HIGH_UL) *10)
    {
      control_State |= CONTROL_FORCE_DECREASE;
    }
    else if (InputReg[REG_TD_IPM] >= GetJDASDParamValue(HREG_IPM_HIGH_NI) *10 )
    {
      control_State |= CONTROL_FORBID_INCREASER;
    }
    else if (InputReg[REG_TD_IPM] >= GetJDASDParamValue(HREG_IPM_HIGH_SL) *10)
    {
      control_State |= CONTROL_SLOW_INCREASE;
    }
 
  }
  else
  {
    if(CMPR_State== ST_STOP)
    {
      cmpr_force_forbit.forbit_dec.byte= 0;
      cmpr_force_forbit.forbit_inc.byte= 0;
      cmpr_force_forbit.force_dec.byte= 0;
      cmpr_force_forbit.force_inc.byte= 0;
    }
  }
  
  if(cmpr_force_forbit.force_dec.byte || cmpr_force_forbit.force_inc.byte)
  {
//    if(!tm_force_inc_dec_sec.start)
//    {
//      Timer_Start(&tm_force_inc_dec_sec);
//    }
		//if(ASDPack.tm_force_inc_dec_sec == 0)
		//ResetCapacityTimer(TM_FORCE_INC_DEC_SEC , 1);
  }
  else
  {
   //Timer_Stop(&tm_force_inc_dec_sec);
		ASDPack.tm_force_inc_dec_sec = 0;
  }
}



void Device_CoolingFan_PV(uint8_t t)
{
 //float diff;
  //float sp;
  float kp, ki, kd;
  float fan_pid_out = 0.0f;
  float pv, setpt;

  kp = GetJDASDParamValue(HREG_FAN_PID_P);//HoldingReg[HR_FAN_PID_P];
  ki = GetJDASDParamValue(HREG_FAN_PID_I);//HoldingReg[HR_FAN_PID_I];
  kd = GetJDASDParamValue(HREG_FAN_PID_D);//HoldingReg[HR_FAN_PID_D];
  kp/= 100.0f;
  ki/= 100.0f;
  kd/= 100.0f;
	
  PID_SetCoeff(&FanPID, kp, ki, kd);
	
//	if(fan_tick < 180000)
//	{
//		fan_tick += t;
//		FanStart = 1;
//	}

  if (InputReg[REG_TEMP_CONDENSITION] >= GetJDASDParamValue(HREG_FAN_START_T) && (InputReg[REG_CMPR_START] || oil_collect_state))
  {
		if(++FanConfirmTimes > 5)
		{
			FanStart = 1;
			FanConfirmTimes = 0;
		}
  }
  else if (InputReg[REG_TEMP_CONDENSITION] < (GetJDASDParamValue(HREG_FAN_START_T)  - GetJDASDParamValue(HREG_FAN_DEADZONE)))
  {
		if(++FanConfirmTimes > 5)
		{
			FanStart = 0;
			FanConfirmTimes = 0;
		}
  }
	else if(InputReg[REG_TEMP_CONDENSITION] == 9999)
	{
		FanConfirmTimes = 0;
	}
	else
	{
		;
	}
  if (FanStart && InputReg[REG_CMPR_START] == 0)
  {
    Delay_Start(&delay_fan_stop);
    if (delay_fan_stop.state)
    {
      FanStart = 0;
    }
  }
  else
  {
    Delay_Stop(&delay_fan_stop);
  }
  
  if (FanStart)
  {
    if (InputReg[REG_PRESS_DISCHG] < 9990 && InputReg[REG_PRESS_DISCHG] > -9990) 
		{
      pv= InputReg[REG_TEMP_CONDENSITION];
      setpt= GetJDASDParamValue(HREG_FAN_START_T) ;//HoldingReg[HR_FAN_START_T];
      pv/=100.0f;
      setpt/= 100.0f;

      fan_pid_out= PID_Control(&FanPID, pv, setpt, t, GetJDASDParamValue(HREG_FAN_PID_DELAY), 0);  //VFD Set, Hz
      fan_pid_out*= GetJDASDParamValue(HREG_FAN_FRQ_MAX);
     // fan_pid_out= _hi_lo_limit(fan_pid_out, HoldingReg[HR_FAN_FRQ_MAX], HoldingReg[HR_FAN_FRQ_MIN]);
			if(fan_pid_out > GetJDASDParamValue(HREG_FAN_FRQ_MAX))
			{
					fan_pid_out = GetJDASDParamValue(HREG_FAN_FRQ_MAX);
			}
			else if (fan_pid_out < GetJDASDParamValue(HREG_FAN_FRQ_MIN))
			{
				fan_pid_out = GetJDASDParamValue(HREG_FAN_FRQ_MIN);
			
			}
      
      cmpr_req.fan_1_rpm = fan_pid_out;
      cmpr_req.fan_2_rpm = fan_pid_out;
    }
		else 
		{
			if(errorState[ERR_PD_FAULT])
			{
				cmpr_req.fan_1_rpm = 72;
				cmpr_req.fan_2_rpm = 72;
				PID_Init(&FanPID, kp, ki, kd, 1, 1);
			}
    }
  }
  else
  {
    cmpr_req.fan_1_rpm = 0;
    cmpr_req.fan_2_rpm = 0;
    PID_Init(&FanPID, kp, ki, kd, 1, 1);
  }
}

void Device_CMPR_Control(uint8_t tick)
{
  float kp, ki, kd;
  float pid_out = 0.0f;
  float pv, setpt;
  int8_t direct = 0;
  int16_t TempValue;
	int16_t i=0;
	int8_t proctims=0;
	
  if (cmpr_tick < 1000)
  {
    cmpr_tick += tick;
  }
  
  if (limit_tick)
  {
    limit_tick-=tick;
  }
	
  if (limit_tick <= 0)
  {
    limit_tick = 0;
  }
  
  //Compressor PID
  //Set PID Coeff
  kp = GetJDASDParamValue(HREG_CMPR_PID_P);//HoldingReg[HR_CMPR_PID_P];
  ki = GetJDASDParamValue(HREG_CMPR_PID_I);//HoldingReg[HR_CMPR_PID_I];
  kd = GetJDASDParamValue(HREG_CMPR_PID_D);//HoldingReg[HR_CMPR_PID_D];
  kp/= 100.0f;
  ki/= 100.0f;
  kd/= 100.0f;
  PID_SetCoeff(&CmprPID, kp, ki, kd);
  
  if (GetJDASDParamValue(HREG_WINTER_MODE))// HoldingReg[HR_WINTER_MODE])
  {
    if((InputReg[REG_TEMP_OUTDOOR] > -3000) && (InputReg[REG_TEMP_OUTDOOR] < 11000))
    {
      if((InputReg[REG_TEMP_OUTDOOR] < GetJDASDParamValue(HREG_WINTER_OUTDOOR_TEMP_SEPT))&&(WinterFlag != 1))
      {
        WinterFlag = 1;
				TempValue = GetJDASDParamValue(HREG_TEMP_EVP_SETPT) + GetJDASDParamValue(HREG_WINTER_EVP_SETPT_DIFF);//HoldingReg[HR_TEMP_EVP_SETPT]
				SetJDASDParamValue(HREG_TEMP_EVP_SETPT, TempValue);
				TempValue = GetJDASDParamValue(HREG_PS_CMPR_STOP) + GetJDASDParamValue(HREG_WINTER_PS_CMPR_STOP_DIFF);//HoldingReg[HR_TEMP_EVP_SETPT]
				SetJDASDParamValue(HREG_PS_CMPR_STOP, TempValue);
        winter_quit_delay = 0;
      }
			else if(WinterFlag)
      {
				if(InputReg[REG_TEMP_OUTDOOR] > GetJDASDParamValue(HREG_WINTER_OUTDOOR_TEMP_SEPT) + GetJDASDParamValue(HREG_WINTER_OUTDOOR_TEMP_DIFF))
				{
					if (winter_quit_delay < GetJDASDParamValue(HREG_WINTER_DELAY))
					{
						winter_quit_delay += tick;
					}
					else
					{
						WinterFlag = 0;
						SetJDASDParamValue(HREG_TEMP_EVP_SETPT, ILoad_Stored_Value(HREG_TEMP_EVP_SETPT * 2));
						SetJDASDParamValue(HREG_PS_CMPR_STOP, ILoad_Stored_Value(HREG_PS_CMPR_STOP * 2));
						winter_quit_delay = 0;
					}
				}
				else
				{
					winter_quit_delay = 0;
				}
      }
    }
    else
    {
      if(WinterFlag)
      {
        WinterFlag = 0;
				SetJDASDParamValue(HREG_TEMP_EVP_SETPT, ILoad_Stored_Value(HREG_TEMP_EVP_SETPT * 2));
				SetJDASDParamValue(HREG_PS_CMPR_STOP, ILoad_Stored_Value(HREG_PS_CMPR_STOP * 2));
        winter_quit_delay = 0;
      }
    }
  }
  else
  {
    if(WinterFlag)
    {
      WinterFlag = 0;
			SetJDASDParamValue(HREG_TEMP_EVP_SETPT, ILoad_Stored_Value(HREG_TEMP_EVP_SETPT * 2));
			SetJDASDParamValue(HREG_PS_CMPR_STOP, ILoad_Stored_Value(HREG_PS_CMPR_STOP * 2));
      winter_quit_delay = 0;
    }
  }
  
  pv= InputReg[REG_TEMP_EVAPORATION];
	setpt= GetJDASDParamValue(HREG_TEMP_EVP_SETPT);
  pv/=100.0f;
  setpt/= 100.0f;

  pid_out= InputReg[REG_PID_OUT];

  if (CMPR_State == ST_RUN)
  {
    if (InputReg[REG_TEMP_EVAPORATION] > ( GetJDASDParamValue(HREG_TEMP_EVP_SETPT) + 5))
    {
      direct = 1;
    }
    else if (InputReg[REG_TEMP_EVAPORATION] < (GetJDASDParamValue(HREG_TEMP_EVP_SETPT) - 5))
    {
      direct = -1;
    }
  }
  if (direct != 0)
  {
    pid_out= PID_Control(&CmprPID, pv, setpt, tick, GetJDASDParamValue(HREG_CMPR_PID_DELAY), Device_CMPR_Freq_Hold(InputReg[REG_PID_OUT], InputReg[REG_CMPR_FRQ]));  //VFD Set, Hz
    pid_out*= up_limit_frequence;// HoldingReg[HR_CMPR_FRQ_MAX];
		
		if(Device_CMPR_Freq_Hold(pid_out, InputReg[REG_CMPR_FRQ]) == 1)
		{
			switch(cmpr_req.cmpr_freq_step)
			{
				case 0:
					pid_out = GetJDASDParamValue(HREG_FREQ_STEP1);
					break;
				case 1:
					pid_out = GetJDASDParamValue(HREG_FREQ_STEP2);
					break;
				case 2:
					pid_out = GetJDASDParamValue(HREG_FREQ_STEP3);
					break;
				case 3:
				default:
					break;
			}
		}
		
		if(pid_out > up_limit_frequence)
		{
				pid_out = up_limit_frequence;
		}
		else if (pid_out < GetJDASDParamValue(HREG_CMPR_FRQ_MIN))
		{
			pid_out = GetJDASDParamValue(HREG_CMPR_FRQ_MIN);
		
		}
  }

  if (Device_Error.drv)
  {
    pid_out= GetJDASDParamValue(HREG_CMPR_FRQ_MIN);//HoldingReg[HR_CMPR_FRQ_MIN];
  }

  if(CMPR_State== ST_RUN || oil_collect_state > 2)
  {
    InputReg[REG_PID_OUT] = pid_out;
    InputReg[REG_PID_HZ] = CmprPID.output * 100;
  }
  else
  {
    InputReg[REG_PID_OUT] = 0;
    InputReg[REG_PID_HZ] = 0;
  }
  // Start/Stop Control
  Device_CMPR_StartStop(tick);
  
  //Frequency Control
  Device_CMPR_FrequcyLimit();
	
  switch(CMPR_Cmd)
  {
    case ST_STOP:
      InputReg[REG_CMPR_START]= 0;
      cmpr_req.cmpr_rps= 0;
      limit_tick = 0;
      limit_max= up_limit_frequence;//HoldingReg[HR_CMPR_FRQ_MAX];
      Device_CMPR_PID_Init();
			Delay_Stop(&transducer_8p_wait);
			Delay_Stop(&transducer_8p_quit);
      break;
    case ST_INIT:
      InputReg[REG_CMPR_START]= 1;
      cmpr_req.cmpr_rps= GetJDASDParamValue(HREG_CMPR_FRQ_INIT);//HoldingReg[HR_CMPR_FRQ_INIT];
      limit_tick = 0;
      limit_max= up_limit_frequence;//HoldingReg[HR_CMPR_FRQ_MAX];
      Device_CMPR_PID_Init();
      break;
    case ST_RUN:
			if (transducer_8p_quit.state)
			{
				Delay_Stop(&transducer_8p_quit);
				transducer_8p_fail = 0;
			}
			
      if (InputReg[REG_PRESS_SUCTION] <= -9990 || InputReg[REG_PRESS_SUCTION] >= 9990
				||InputReg[REG_PRESS_DISCHG] <= -9990 || InputReg[REG_PRESS_DISCHG] >= 9990
					|| InputReg[REG_TEMP_DISCHG] <= -3000 || InputReg[REG_TEMP_DISCHG] >= 15000
						|| InputReg[REG_TEMP_SUCTION] <= -3000 || InputReg[REG_TEMP_SUCTION] >= 10500)
			{
        cmpr_req.cmpr_rps = 50;
        break;
      }
			
      if (oil_collect_state)
      {
        break;
      }
			
      if (InputReg[REG_TEMP_EVAPORATION] > (GetJDASDParamValue(HREG_TEMP_EVP_SETPT) + 5))
      {
        direct = 1;
      }
      else if (InputReg[REG_TEMP_EVAPORATION] < (GetJDASDParamValue(HREG_TEMP_EVP_SETPT) - 5))
      {
        direct = -1;
      }
			
			if ((HAL_DI_GetSwitchValue() & 0xC0) == 0xC0)			
			{ // 8P
				if (transducer_8p_wait.state)
				{
					transducer_8p_fail = 0;
				}
		  }
			
			
			InputReg[REG_47]= cmpr_req.cmpr_rps;
			InputReg[REG_86] = cmpr_force_forbit.forbit_dec.byte;
			
			
      if ((control_State & CONTROL_FORCE_DECREASE) 
        || (control_State & CONTROL_FORBID_INCREASER)
					|| cmpr_force_forbit.forbit_dec.byte)
      {
        limit_max = cmpr_ack.cmpr_rps;
        limit_tick = 90;
        if (cmpr_req.control_state == 0)
        {
          cmpr_req.control_state = 1;
          cmpr_req.cmpr_rps = cmpr_ack.cmpr_rps;
					
        }
				
      }
      else
      {
        cmpr_req.control_state = 0;
      }
      
      if (control_State & CONTROL_FORCE_DECREASE)
      {
        if (cmpr_tick >= GetJDASDParamValue(HREG_FAST_DESC_TERM))
        {
          if (cmpr_req.cmpr_rps > GetJDASDParamValue(HREG_FORCE_DECREASE_BUTTOM))
          {
            cmpr_req.cmpr_rps --;
            cmpr_tick = 0;
          }
        }
				InputReg[REG_87] = 1;
			
      }
      else if (control_State & CONTROL_FORBID_INCREASER)
      {
        if (GetJDASDParamValue(HREG_CMPR_PID_EN))
        {
          if (pid_out < cmpr_req.cmpr_rps)
          {
            cmpr_req.cmpr_rps = pid_out;
            cmpr_tick = 0;
          }
        }
        else
        {
          if (direct < 0)
          {
            if (cmpr_tick >= GetJDASDParamValue(HREG_DESC_TERM))
            {
              cmpr_req.cmpr_rps --;
              cmpr_tick = 0;
            }
          }
        }
				InputReg[REG_87] = 2;
				
			
      }
      else if (control_State & CONTROL_SLOW_INCREASE)
      {
        if (GetJDASDParamValue(HREG_CMPR_PID_EN))
        {
          if (pid_out <= cmpr_req.cmpr_rps)
          {
            cmpr_req.cmpr_rps = pid_out;
            cmpr_tick = 0;
          }
          else
          {
            if (cmpr_tick >= GetJDASDParamValue(HREG_SLOW_INCR_TERM))
            {
							if (Device_CMPR_Freq_Hold(cmpr_req.cmpr_rps, InputReg[REG_CMPR_FRQ]) == 0)
							{
								cmpr_req.cmpr_rps ++;
							}
              cmpr_tick = 0;
            }
          }
        }
        else
        {
          if (direct < 0)
          {
            if (cmpr_tick >= GetJDASDParamValue(HREG_DESC_TERM))
            {
              cmpr_req.cmpr_rps = cmpr_ack.cmpr_rps - 1;
              cmpr_tick = 0;
            }
          }
          else if (direct > 0)
          {
            if (cmpr_tick >= GetJDASDParamValue(HREG_SLOW_INCR_TERM))
            {
							if (Device_CMPR_Freq_Hold(cmpr_req.cmpr_rps, InputReg[REG_CMPR_FRQ]) == 0)
							{
								cmpr_req.cmpr_rps ++;
							}
              cmpr_tick = 0;
            }
          }
        }
				InputReg[REG_87] = 3;
				
      }
      else
      {
        if(cmpr_force_forbit.force_inc.byte)    //Force Inc
        {
         // if(Timer_Expires(&tm_force_inc_dec_sec))
					if(ASDPack.tm_force_inc_dec_sec == 0)
          {
            cmpr_req.cmpr_rps+= 1;//3;
            if(cmpr_req.cmpr_rps > up_limit_frequence)
            {
              cmpr_req.cmpr_rps= up_limit_frequence;
              cmpr_tick = 0;
            }
						ResetCapacityTimer(TM_FORCE_INC_DEC_SEC , 1);
          }
					InputReg[REG_87] = 4;
					
			
        }
        else
        {
          if(cmpr_force_forbit.forbit_dec.byte)  //Forbid Dec
          {
            if (GetJDASDParamValue(HREG_CMPR_PID_EN))
            {
              if(pid_out > cmpr_req.cmpr_rps)
              {
                cmpr_req.cmpr_rps= pid_out;    //Hz
                cmpr_tick = 0;
              }
            }
            else
            {
              if (direct > 0)
              {
                if (cmpr_tick >= GetJDASDParamValue(HREG_INCR_TERM))
                {
									if (Device_CMPR_Freq_Hold(cmpr_req.cmpr_rps, InputReg[REG_CMPR_FRQ]) == 0)
									{
										cmpr_req.cmpr_rps ++;
									}
                  cmpr_tick = 0;
                }
              }
            }
						
				   InputReg[REG_87] = 5;
          }
          else
          {
            if (GetJDASDParamValue(HREG_CMPR_PID_EN))
            {
              cmpr_req.cmpr_rps = pid_out;
              cmpr_tick = 0;
							InputReg[REG_87] = 6;
            }
            else
            {
              if (direct < 0)
              {
                if (cmpr_tick >= GetJDASDParamValue(HREG_DESC_TERM))
                {
                  cmpr_req.cmpr_rps --;
                  cmpr_tick = 0;
                }
              }
              else if (direct > 0)
              {
                if (cmpr_tick >= GetJDASDParamValue(HREG_INCR_TERM))
                {
									if (Device_CMPR_Freq_Hold(cmpr_req.cmpr_rps, InputReg[REG_CMPR_FRQ]) == 0)
									{
										cmpr_req.cmpr_rps ++;
									}
                  cmpr_tick = 0;
                }
              }
							InputReg[REG_87] = 7;
            }
          }			
        }
      }
      
      if(cmpr_req.cmpr_rps < GetJDASDParamValue(HREG_CMPR_FRQ_MIN))
      {
        cmpr_req.cmpr_rps = GetJDASDParamValue(HREG_CMPR_FRQ_MIN);
      }
		
      break;
    default:
      break;
  }
	
  InputReg[REG_ADC_P3]= limit_max;
	
  if (limit_tick > 0 && (limit_max < up_limit_frequence - 5) )
  {
    if(cmpr_req.cmpr_rps > limit_max + 5)
    {
      cmpr_req.cmpr_rps = limit_max + 5;
    }
		InputReg[REG_48]= cmpr_req.cmpr_rps;
  }
  else
  {
    if(cmpr_req.cmpr_rps > up_limit_frequence)
    {
      cmpr_req.cmpr_rps = up_limit_frequence;
    }
  }

  cmpr_req.cmpr_target = cmpr_req.cmpr_rps;
	
  if (cmpr_req.cmpr_rps >= GetJDASDParamValue(HREG_CMPR_FRQ_MIN) && cmpr_req.cmpr_rps < up_limit_frequence)
  {
    if (cmpr_req.cmpr_rps > GetJDASDParamValue(HREG_TRANS_AVOID_BUTTOM)
      && cmpr_req.cmpr_rps < (GetJDASDParamValue(HREG_TRANS_AVOID_BUTTOM) + GetJDASDParamValue(HREG_TRANS_AVOID_WIDE) / 2))
    {
      cmpr_req.cmpr_target = GetJDASDParamValue(HREG_TRANS_AVOID_BUTTOM);
    }
    else if (cmpr_req.cmpr_rps >= (GetJDASDParamValue(HREG_TRANS_AVOID_BUTTOM) + GetJDASDParamValue(HREG_TRANS_AVOID_WIDE) / 2)
      && cmpr_req.cmpr_rps < (GetJDASDParamValue(HREG_TRANS_AVOID_BUTTOM) + GetJDASDParamValue(HREG_TRANS_AVOID_WIDE)))
    {
      if (control_State & CONTROL_FORCE_DECREASE)
      {
        cmpr_req.cmpr_target = GetJDASDParamValue(HREG_TRANS_AVOID_BUTTOM);
      }
      else
      {
        cmpr_req.cmpr_target = GetJDASDParamValue(HREG_TRANS_AVOID_BUTTOM) + GetJDASDParamValue(HREG_TRANS_AVOID_WIDE);
      }
    }
		
		proctims = 0;
		
		while((cmpr_req.cmpr_target == GetJDASDParamValue(HREG_TRANS_AVOID_P1) || cmpr_req.cmpr_target == GetJDASDParamValue(HREG_TRANS_AVOID_P2)
				|| cmpr_req.cmpr_target == GetJDASDParamValue(HREG_TRANS_AVOID_P3) || cmpr_req.cmpr_target == GetJDASDParamValue(HREG_TRANS_AVOID_P4)
					|| cmpr_req.cmpr_target == GetJDASDParamValue(HREG_TRANS_AVOID_P5)))
		{
			if(CMPR_State != ST_RUN || proctims >= 6)
			{
				break;
			}
			if (((control_State & CONTROL_SLOW_INCREASE) || (control_State & CONTROL_FORBID_INCREASER)) && (cmpr_req.cmpr_target < up_limit_frequence))
			{
				cmpr_req.cmpr_target ++;
			}
			else if((control_State & CONTROL_FORCE_DECREASE) && (control_State & CONTROL_FORBID_INCREASER) && (cmpr_req.cmpr_target > GetJDASDParamValue(HREG_CMPR_FRQ_MIN)))
			{
				cmpr_req.cmpr_target --;
			}
			else
			{
				if((InputReg[REG_CMPR_DIRECT] > 0) && (cmpr_req.cmpr_target < up_limit_frequence))
				{
					cmpr_req.cmpr_target ++;
				}
				else if((InputReg[REG_CMPR_DIRECT ] < 0) &&  (cmpr_req.cmpr_target > GetJDASDParamValue(HREG_CMPR_FRQ_MIN)))
				{
					cmpr_req.cmpr_target --;
				}
				else if(cmpr_req.cmpr_target < up_limit_frequence)
				{
					cmpr_req.cmpr_target ++;
				}
				
				if(cmpr_req.cmpr_target == up_limit_frequence)
				{
					for(i=0; i<6; i++)
					{
						cmpr_req.cmpr_target --;
						if(cmpr_req.cmpr_target != GetJDASDParamValue(HREG_TRANS_AVOID_P1) || cmpr_req.cmpr_target != GetJDASDParamValue(HREG_TRANS_AVOID_P2)
							|| cmpr_req.cmpr_target != GetJDASDParamValue(HREG_TRANS_AVOID_P3) || cmpr_req.cmpr_target != GetJDASDParamValue(HREG_TRANS_AVOID_P4)
								|| cmpr_req.cmpr_target != GetJDASDParamValue(HREG_TRANS_AVOID_P5))
						{
							break;
						}
					}
				}
				
				if(cmpr_req.cmpr_target == GetJDASDParamValue(HREG_CMPR_FRQ_MIN))
				{
					for(i=0; i<6; i++)
					{
						cmpr_req.cmpr_target ++;
						if(cmpr_req.cmpr_target != GetJDASDParamValue(HREG_TRANS_AVOID_P1) || cmpr_req.cmpr_target != GetJDASDParamValue(HREG_TRANS_AVOID_P2)
							|| cmpr_req.cmpr_target != GetJDASDParamValue(HREG_TRANS_AVOID_P3) || cmpr_req.cmpr_target != GetJDASDParamValue(HREG_TRANS_AVOID_P4)
								|| cmpr_req.cmpr_target != GetJDASDParamValue(HREG_TRANS_AVOID_P5))
						{
							break;
						}
					}
				}
			}
			proctims ++;
		}
  }
 	InputReg[REG_FREQ_HOLD] = cmpr_req.cmpr_freq_step;
	InputReg[REG_POWERON_TIME] = cmprOnSeconds;
  InputReg[REG_CMPR_TICK] = cmpr_tick;
  InputReg[REG_CONTROL_STATE] = control_State;
  InputReg[REG_CMPR_CMD] = CMPR_Cmd;
  InputReg[REG_CMPR_DIRECT] = direct;
  InputReg[REG_VALVE_2] = InputReg[REG_CMPR_START] | ((oil_collect_state > 1) ? 1:0);
}

void Jetting_liquid_Progress(uint8_t tick)
{
	s16 start_td = GetJDASDParamValue(HREG_JETLIQ_START_TD)*10;
	s16 start_freq = GetJDASDParamValue(HREG_JETLIQ_START_FREQ);
	s16 stop_td = GetJDASDParamValue(HREG_JETLIQ_STOP_TD)*10;
	s16 bdcr_dev = GetJDASDParamValue(HREG_JETLIQ_BDCR_DEV)*10;
	s16 lstp_open = GetJDASDParamValue(HREG_JETLIQ_LSTP_OPEN)*10;
	s16 ustp_open = GetJDASDParamValue(HREG_JETLIQ_USTP_OPEN)*10;
	s16 stp0 = GetJDASDParamValue(HREG_JETLIQ_0STP_OPEN);
	s16 stp1 = GetJDASDParamValue(HREG_JETLIQ_1STP_OPEN);
	s16 stp2 = GetJDASDParamValue(HREG_JETLIQ_2STP_OPEN);
	s16 stp3 = GetJDASDParamValue(HREG_JETLIQ_3STP_OPEN);
	
	if(InputReg[REG_CMPR_WRITE] ==0)
	{
		EEValveState.pos_set = 0;
		InputReg[REG_VALVE_1] = 0;
		return;
	}
	
	if(InputReg[REG_TEMP_DISCHG] <= -3000 || InputReg[REG_TEMP_DISCHG] >= 15000)
	{
		if(CMPR_Cmd == ST_RUN)
		{
			EEValveState.pos_set = 100;
			InputReg[REG_VALVE_1] = 1;
		}
		else
		{
			EEValveState.pos_set = 0;
			InputReg[REG_VALVE_1] = 0;
		}
		return;
	}
	
	if(CMPR_State == ST_RUN && oil_collect_state == 0 
		&& InputReg[REG_TEMP_DISCHG] >= start_td 
			&& InputReg[REG_CMPR_FRQ] >= start_freq)
	{
		Delay_Start(&delay_jet_liq_on);
		Delay_Start(&delay_jet_liq_off);
		
		if(delay_jet_liq_on.state)
		{
			InputReg[REG_VALVE_1] = 1;
			Delay_Stop(&delay_jet_liq_on);
		}
	}
	else
	{
		Delay_Stop(&delay_jet_liq_on);
		
		if(delay_jet_liq_off.state && ((CMPR_State == ST_STOP) || InputReg[REG_TEMP_DISCHG] < stop_td 
			|| oil_collect_state == 1))
		{
			InputReg[REG_VALVE_1] = 0;
			Delay_Stop(&delay_jet_liq_off);
		}
	}
	
	if(InputReg[REG_VALVE_1]==1)
	{
		switch(EEValveState.sta_cycl)
		{
			case 0:
				EEValveState.pos_set = stp0;
				if(InputReg[REG_TEMP_DISCHG] >= start_td)
				{
					EEValveState.sta_cycl = 1;
				}
				break;
			case 1:
				EEValveState.pos_set = stp1;
				if(InputReg[REG_TEMP_DISCHG] < stop_td)
				{
					EEValveState.sta_cycl = 0;
					InputReg[REG_VALVE_1] = 0;
				}
				if(InputReg[REG_TEMP_DISCHG] >= lstp_open)
				{
					EEValveState.sta_cycl = 2;
				}
				break;
			case 2:
				EEValveState.pos_set = stp2;
				if(InputReg[REG_TEMP_DISCHG] < (lstp_open - bdcr_dev))
				{
					EEValveState.sta_cycl = 1;
				}
				if(InputReg[REG_TEMP_DISCHG] >= ustp_open)
				{
					EEValveState.sta_cycl = 3;
				}
				break;
			case 3:
				EEValveState.pos_set = stp3;
				if(InputReg[REG_TEMP_DISCHG] < (ustp_open - bdcr_dev))
				{
					EEValveState.sta_cycl = 2;
				}
				break;
		}
	}
	else
	{
		EEValveState.sta_cycl = 0;
		EEValveState.pos_set= 0;

	}
}

uint8_t getNextError(void)
{
  uint8_t i = 0;
  for (i = 0; i < ERROR_STATE_SIZE; i++) 
	{
    if (errorStateIndex >= ERROR_STATE_SIZE - 1)
    {
      errorStateIndex = 0;
    }
    else
    {
      errorStateIndex ++;
    }
    if (errorState[errorStateIndex] != 0)
    {
      return errorStateIndex;
    }
  }
  return 0;
}


u8 GetFactoryTest(void)
{
	return factory_test;

}


u8 Getfactory_test_stage(void)
{
	return factory_test_stage;

}

u8 Getfactory_test_error(void)
{
	return factory_test_error;

}

u8 ASD_Control(	void	)
{
  u32 TicksNow, TicksElapsed;
	
	TicksNow = Timer2_Get32Ticks();
	TicksElapsed = TicksNow - Update;
	
	if(TicksElapsed < ASD_UPDATE_DELAY)
	{
		return 0;
	}
	Update = Timer2_Get32Ticks();
	
	if(TicksNow >= TimersSecondUpdate)
	{
		TicksElapsed = TicksNow - TimersSecondUpdate;
	}
	else
	{
		TicksElapsed = TicksNow + (0xFFFFFFFF - TimersSecondUpdate);
	}
	
	if(TicksElapsed > 1000)
	{
		TimersSecondUpdate = Timer2_Get32Ticks();		
		DecrementTimers();
		
//		if(InputReg[REG_TEMP_OUTDOOR] >= 430)
//		{
//			up_limit_frequence = GetJDASDParamValue(HREG_OVLD_FREQ);
//		}
//		else
//		{
//			up_limit_frequence = GetJDASDParamValue(HREG_CMPR_FRQ_MAX);
//		}
		up_limit_frequence = GetJDASDParamValue(HREG_CMPR_FRQ_MAX);
		
		if(cmprOnSeconds < 3600 && CMPR_Start_Flag == 1 && InputReg[REG_CMPR_START] == 1)
		{
			cmprOnSeconds++;
		}
		
		if(ASDPack.PowerOnWaitTimer)
		{
			return 0;
		}
		
		UpdateCompOutput();
		UpdateFanOutput();
		UpdateElecVale();
	}
	
	if(ASDPack.PowerOnWaitTimer)
	{
		return 0;
	}

	Device_GetInputValue();
	UpdateCompStatus();
	
  if (init_delay) 
	{
    InputReg[REG_FCT_IN_DI] = IGet_DI_State(DI_FCTRY_TEST);
    InputReg[REG_FCT_IN_FL] = (GetJDASDParamValue(HREG_FACTORY_TEST_FLAG) != FACTORY_TEST_TAG)? 1:0;
    factory_test = InputReg[REG_FCT_IN_DI] | InputReg[REG_FCT_IN_FL];
    ASDPack.SysStatus = STATUS_INIT;
		sec_flag = 0;
    return 0;
  }

  if(factory_test)
  {
    do_factory_test(delay_sec_flag);
    
    if(( factory_test_stage == 21)||(factory_test_stage == 127))
    {
      if(factory_test_delay == 0)
      {
        factory_test = 0;    
      }
    }
  
    sec_flag = 0;
		ASDPack.SysStatus = STATUS_INIT;
    return 0;
  }
	
	Device_CMPR_Heater();
	DecrementMSTimers();
	
	if (start_delay>0 || (delay_heater.ticks>0 && delay_heater.over==0))
  {
		
    sec_flag = 0;
		ASDPack.SysStatus = STATUS_INIT;
    return 0;
  }
	
	//Device_ExpansionValve();
	Device_CMPR_Control(sec_flag);
	Device_CoolingFan_PV(sec_flag);
	Oil_Collect_Progress(sec_flag);
	Device_SetOutputValue();
	Jetting_liquid_Progress(sec_flag);
	sec_flag = 0;
	return (u8)0;
}


void Device_Timer_Init(void)
{
  Delay_Set(&delay_cmpr_run_on_fail, 300);
  Delay_Set(&delay_cmpr_stop_on_fail, 120);
	Delay_Set(&delay_cmpr_run_on_fail_ot, 300);
	Delay_Set(&delay_heater, GetJDASDParamValue(HREG_HEATE_TIME)*60);
  Delay_Set(&delay_cmpr_stop_on_fail_ot, 180);
  Delay_Set(&delay_err_reset, 32);
  Delay_Set(&delay_ps_gt_psu, 3);
  Delay_Set(&delay_ps_lt_psu, GetJDASDParamValue(HREG_WAITSTOP_DELAY));//180);
  Delay_Set(&delay_ps_lo, 1);
  Delay_Set(&delay_td_hi, 1);
  Delay_Set(&delay_pd_hi, 1);
  Delay_Set(&delay_pd_flt, 5);
  Delay_Set(&delay_ps_flt, 5);
	Delay_Set(&delay_td_flt, 5);
	Delay_Set(&delay_ts_flt, 5);
	Delay_Set(&delay_os_flt, 5);
  Delay_Set(&delay_tssh_lo, 180);
  Delay_Set(&delay_freq_lo_pd_hi, 300);
	Delay_Set(&delay_cmpr_hold, GetJDASDParamValue(HREG_FREQ_HDTIME));
	Delay_Set(&delay_ipm_temp_hi, 3);
  Delay_Set(&delay_cmpr_init, GetJDASDParamValue(HREG_CMPR_INIT_TIME));
  Delay_Set(&delay_cmpr_pd_ps_lo, 300);    //Pd/Ps
  Delay_Set(&delay_eev_init, 60);
  Delay_Set(&delay_twinkle, 1);
  Delay_Set(&delay_keypad_set, 10);
  Delay_Set(&td_hi_err_reset, 420);        //7 Minutes
  Delay_Set(&td_hi_times_reset, 3600);    //1 Hour
  Delay_Set(&delay_cmpr_err_times_reset, 1800);
  Delay_Set(&transducer_8p_wait, 30);
  Delay_Set(&transducer_8p_quit, 60);
  Delay_Set(&delay_oil_collect_30, 30);
  Delay_Set(&delay_oil_collect_3, 3);
	Delay_Set(&delay_jet_liq_on,GetJDASDParamValue(HREG_JETLIQ_COND_TIM));
	Delay_Set(&delay_jet_liq_off,3);
	Delay_Set(&delay_fan_stop, 10);
	Delay_Set(&delay_fan1_start, 1);
	Delay_Set(&delay_fan1_trm, 2);
	Delay_Set(&delay_fan1_fault, 10);
	Delay_Set(&delay_fan1_recover, 35);
	Delay_Set(&delay_fan2_start, 1);
	Delay_Set(&delay_fan2_trm, 2);
	Delay_Set(&delay_fan2_fault, 10);
	Delay_Set(&delay_fan2_recover, 35);
}

void unitTypeChanged(uint8_t ut)
{
  uint8_t t = ut & 3;
	
  switch (t)
  {
    case 0: // 3P
			SetParamRegisterValue(HREG_AC_HIGH_STOP, 24);
			SetParamRegisterValue(HREG_AC_HIGH_UL, 22);
			SetParamRegisterValue(HREG_AC_HIGH_NI, 20);
			SetParamRegisterValue(HREG_AC_HIGH_SL, 19);
			SetParamRegisterValue(HREG_DC_HIGH_STOP, 110);
			SetParamRegisterValue(HREG_DC_HIGH_UL, 90);
			SetParamRegisterValue(HREG_DC_HIGH_NI, 80);
			SetParamRegisterValue(HREG_DC_HIGH_SL, 70);
			SetParamRegisterValue(HREG_TRANS_AVOID_BUTTOM, 0);
			SetParamRegisterValue(HREG_TRANS_AVOID_BUTTOM, 1);
			break;
    case 1: // 6P
			SetParamRegisterValue(HREG_AC_HIGH_STOP, 33);
		  SetParamRegisterValue(HREG_AC_HIGH_UL, 30);		
			SetParamRegisterValue(HREG_AC_HIGH_NI, 28);
			SetParamRegisterValue(HREG_AC_HIGH_SL, 26);
			SetParamRegisterValue(HREG_DC_HIGH_STOP, 143);
			SetParamRegisterValue(HREG_DC_HIGH_UL, 133);
			SetParamRegisterValue(HREG_DC_HIGH_NI, 123);
			SetParamRegisterValue(HREG_DC_HIGH_SL, 113);
			SetParamRegisterValue(HREG_FAN_FRQ_MAX, 78);
			SetParamRegisterValue(HREG_JETLIQ_START_TD, 95);
			SetParamRegisterValue(HREG_JETLIQ_COND_TIM, 30);
			SetParamRegisterValue(HREG_JETLIQ_STOP_TD, 85);
			SetParamRegisterValue(HREG_JETLIQ_3STP_OPEN, 350);
			SetParamRegisterValue(HREG_JETLIQ_2STP_OPEN, 250);
			SetParamRegisterValue(HREG_JETLIQ_1STP_OPEN, 150);
			SetParamRegisterValue(HREG_TRANS_AVOID_P1, 42);
			SetParamRegisterValue(HREG_TRANS_AVOID_P2, 50);
			SetParamRegisterValue(HREG_TRANS_AVOID_P3, 1);
			SetParamRegisterValue(HREG_TRANS_AVOID_P4, 1);
			SetParamRegisterValue(HREG_TRANS_AVOID_P5, 1);
			SetParamRegisterValue(HREG_FREQ_STEP1, 40);
			SetParamRegisterValue(HREG_FREQ_STEP2, 70);
			SetParamRegisterValue(HREG_FREQ_STEP3, 120);
			SetParamRegisterValue(HREG_FREQ_HDTIME, 300);
			SetParamRegisterValue(HREG_OVLD_FREQ, 120);
      break;
    case 3: // 8P		
			SetParamRegisterValue(HREG_AC_HIGH_STOP, 34);
		  SetParamRegisterValue(HREG_AC_HIGH_UL, 32);
			SetParamRegisterValue(HREG_AC_HIGH_NI, 30);
			SetParamRegisterValue(HREG_AC_HIGH_SL, 28);
			SetParamRegisterValue(HREG_DC_HIGH_STOP, 240);
			SetParamRegisterValue(HREG_DC_HIGH_UL, 230);
			SetParamRegisterValue(HREG_DC_HIGH_NI, 220);
			SetParamRegisterValue(HREG_DC_HIGH_SL, 210);
			SetParamRegisterValue(HREG_TRANS_AVOID_BUTTOM, 0);
			SetParamRegisterValue(HREG_TRANS_AVOID_BUTTOM, 1);
			SetParamRegisterValue(HREG_FAN_FRQ_MAX, 83);
			SetParamRegisterValue(HREG_JETLIQ_START_TD, 95);
			SetParamRegisterValue(HREG_JETLIQ_COND_TIM, 30);
			SetParamRegisterValue(HREG_JETLIQ_STOP_TD, 85);
			SetParamRegisterValue(HREG_JETLIQ_3STP_OPEN, 450);
			SetParamRegisterValue(HREG_JETLIQ_2STP_OPEN, 350);
			SetParamRegisterValue(HREG_JETLIQ_1STP_OPEN, 200);
			SetParamRegisterValue(HREG_TRANS_AVOID_P1, 1);
			SetParamRegisterValue(HREG_TRANS_AVOID_P2, 1);
			SetParamRegisterValue(HREG_TRANS_AVOID_P3, 1);
			SetParamRegisterValue(HREG_TRANS_AVOID_P4, 1);
			SetParamRegisterValue(HREG_TRANS_AVOID_P5, 1);
			SetParamRegisterValue(HREG_FREQ_STEP1, 40);
			SetParamRegisterValue(HREG_FREQ_STEP2, 70);
			SetParamRegisterValue(HREG_FREQ_STEP3, 120);
			SetParamRegisterValue(HREG_FREQ_HDTIME, 300);
			SetParamRegisterValue(HREG_OVLD_FREQ, 120);
      break;
  }
}

uint16_t testtype[3];

uint8_t Pack_Init(void)
{
	uint8_t unit_type = HAL_DI_GetSwitchValue() >> 6;

	testtype[0] = HAL_DI_GetSwitchValue();
	testtype[1] =  HAL_DI_GetSwitchValue() >> 6;

	if(GetJDASDParamValue(HREG_COMPRESSOR_POWER) != unit_type)
	{
		unitTypeChanged(unit_type);	     
		SetParamRegisterValue(HREG_COMPRESSOR_POWER, unit_type);//

	}
	
	memset(levela_error,0,2);
	memset(levelb_error,0,2);
	memset(levelc_error,0,20);
	memset(leveld_error,0,4);
	memset(levele_error,0,2);
	
	up_limit_frequence = GetJDASDParamValue(HREG_CMPR_FRQ_MAX);
	// cmpr_req.Lastcmpr_target = 0xff;
	cmpr_req.cmpr_rps = 0;
	cmpr_req.cmpr_freq_step = 0;
	cmpr_req.fan_1_rpm = 0;
	cmpr_req.fan_2_rpm = 0;
	cmpr_speed = 0;
	Last_cmpr_speed = 0xff;
	Last_fan_speed[0] =  0xff;
	Last_fan_speed[1] =  0xff;
	FanConfirmTimes = 0;
	fan_tick = 0;
	cmprOnSeconds = 0;
	Device_CMPR_PID_Init();
	ISet_DO_Break(DO_CHN_5);
	Device_ExpansionValve_Init();
	factory_test_delay = 5 * 60;
	ASDPack.PowerOnWaitTimer = 5;
	ASDPack.lastSysStatus = 0xff;	 
	Device_Timer_Init();
	InputReg[REG_SOFT_VERSION] = SOFTWARE_VERSION;
	return 0;    

}


u8 SetJDASDParamValue( u16  location, s16 Value)
{
	SetParamValue(location, Value);  

	switch(location)
	{
		default:
			break;

	}

	return 0;
}


/*
 * Function Name:   GetJDDSCStatuesValue
 * Description: ??Input????
 * Return Value:    s16 ??16?????
 * Parameter:   index   ?????
 * Note:
 */
s16 GetJDASDStatuesValue(u16 Address)
{
	return InputReg[Address];

}

